Wielokrotne dziedziczenie i rzutowanie

0

Czesc, mam krotkie pytanko.

mam klase:

class C : public A, public B

teraz robie sobie np.

C objC = new C();

i potem chciałbym rzutować C na B czyli

B objB = (B)objC;

w jaki sposób zrobić to poprawnie?

pzdr
squash

jeśli utworzę sobie obiekt klasy C

0

Zasadniczo tak jak pokazałeś, ale licz się z tym że zrobi sie tutaj slicing, tzn obiekt klasy pochodnej zostanie obcięty do obiektu klasy bazowej. Tego właśnie chcesz?

0

Na początku chciałbym podziękować za odpowiedź :)

Dokladnie tego chcę.
Chcę po po prostu wyłuskać jedynie dane, które zawarte są w B
Przed chwilką sprawdziłem i rzeczywiście to, co napisałeś jest poprawne.
Zadałem to pytanie, ponieważ tak naprawdę testowałem troszkę inny kod wyglądał on tak:

class C : public A, public B
A objA = new objC();
B objB = (B)objA

to rzutowanie nie dawało poprawnego wyniku (w objB pojawiały się krzaki)
natomiast rzutowanie:

A objA = new objC();
C objC = (C)objA

dawało poprawne dane.

musiałem więc zrobić:

A objA = new objC();
C objC = (C)objA;
B objB = (B)objC;

wtedy objB zawierał poprawne dane

Czy takie zachowanie wynika z kolejności w jakiej zapisane jest dziedziczenie ? czyli:

class C : public A, public B

pzdr
squash

0

Nie. Wynika z tego że OBCINAMY. Po zrobieniu:

A objA = new objC();

w objA zostaje nam TYLKO kawalek odpowiedzialny za A i NIC więcej. Tak jakbyś obciął z obiektu C cały kawałek odpowiedzialny za B (i ew bonusowe rzeczy które dodałeś w C). To tak jakbyś miał klase Ciężarówka i dziedziczącą z niej Ciężarówka_Z_Naczepą. Jak zrzutujesz sobie cieżarówkę z naczepą na ciężarówkę to tak jakbyś tą naczepę urwał. Tej naczepy juz nie ma.
A to:

C objC = (C)objA;

To terroryzm zwany nieuprawionym rzutowaniem w górę. NIE WOLNO tak robić. Masz obiekt A a wmawiasz kompilatorowi że to jest obiekt C (kiedy to wcale nie jest obiekt C!). Tzn urwałes naczepę ale próbujesz wszystkim wmówić ze ona tam jest...

Takie cuda które chcesz zrobić wolno ci robić TYLKO z referencjami i wskaźnikami, bo wtedy nie masz slicingu - obcinania, tylko wskazywanie obiektu pochodnego przez wskaźnik do obiektu bazowego.

0

oczywiście masz rację, rzutowanie w górę na obiektach bez wskaźników to terroryzm,
w rzeczywistości działam na wskaźnikach
skopałem sprawę, bo kod który tu generuję jest pseudo kodem, który ma uprościć analizę
wynika to z tego, że z 98% kodu pisze w c# i nie mam nawyku wstawiać znaków wskaźnika :)
C++ stosuje jako DLL dla przyśpieszenia pewnych obliczeń

powinno być oczywiście:

1. A *objA = new objC();
2. C *objC = (C*)objA;
3. B *objB = (B*)objA;

moje pytanie w takim razie brzmi:
dlaczego rzutowanie w linijce 2 da oczekiwane rezultaty a już w 3 linijce mam krzaki ?

pzdr
squash

0

Zastanów się chwilę co właściwie się dzieje kiedy tak rzutujesz.
Domyślam się że kompilator sobie ten wskaźnik odpowiednio ustawia -> tzn jak robisz
A *objA = new objC();
to kompilator ten wskaźnik A ustawia na fragment objC gdzie siedzi nam A, a ty następnie próbujesz zrobić takie rzutowanie w bok.
Zauważ jak to wygląda z punktu widzenia kompilatora:
on widzi ze masz wskaźnik na obiekt A a chcesz rzutować na wskaźnik na obiekt B kiedy A i B NIE SĄ POWIĄZANE ZE SOBĄ żadną hierarchią!
Co gorsza, znów próbujesz go okłamać wmawiając mu że masz tam wskaźnik na obiekt C.

0

Przypuszczam, że sam jestem w stanie odpowiedzieć sobie na to pytanie :)

Zapewne rzutując w 3 linijce, wskaźnik objA zawierając w sobie dane zarówno o C jak i B nie jest w stanie inteligentnie rozpoznać, który fragment pamięci przeznaczyć na rzutowanie. Bierze po prostu to, co znajduje się od razu przy adresie wskaźnika i obcina do rozmiaru klasy, na którą chcemy rzutować.

pzdr
squash

0

czyli dobrze wydedukowalem :)

jeszcze raz dzieki za zainteresowanie

pzdr
squash

0

Rzutowaniem dynamicznym dynamic_cast<> możesz rzutować pomiędzy tymi trzema typami jak chcesz, zawsze będzie poprawnie.
Jedyne ograniczenie - każda z tych klas musi mieć przynajmniej jedną (dowolną) funkcje wirtualną.

0

dzieki za info :)

na pewno sie przyda w przyszlosci

pzdr
squash

1 użytkowników online, w tym zalogowanych: 0, gości: 1