Dziedziczenie wirtualne - skutki

2012-01-20 13:09
0

Czytam dokumentację C++11 dokładniej o dziedziczeniu wirtualnym, bo znalazłem ten post
http://4programmers.net/Forum/C_i_C++/173933-c++_klasa_finalna_po_co_taki_zabieg
Shalom tu wspomniał, że dziedziczenie wirtualne omija "wężyk" tworzenia klas. W książce (na dotatek tylko jednej które czytałem) była mowa tylko o zapobieganiu duplikowania klasy bazowej.
Przeczytałem też to co jest w linku od Azraela, jest tam napisane, że jeżeli klasa jest dziedziczona wirtualnie, to najbardziej pochodna klasa wywołuje konsturktor klasy bazowej dziedziczonej wirtualnie Od razu. Ale jak stworzyłem "gadatliwe konstruktory" to okazuje się, że są wywoływane w tej samej kolejności co przy dziedziczeniu zwykłym. Może mi ktoś dać odnośnik do tego w dokumentacji?


Gdy się nie wie, co się robi, to dzieją się takie rzeczy, że się nie wie, co się dzieje ;-)

Pozostało 580 znaków

2012-01-20 16:37
0

Chciałbym dowiedzieć się czegoś na ten temat, dlatego pozwolę sobie odświeżyć temat jednocześnie przepraszając gospodarzy za spam.


Gdy się nie wie, co się robi, to dzieją się takie rzeczy, że się nie wie, co się dzieje ;-)

Pozostało 580 znaków

2012-01-20 16:52

Nie kolejność wywoływania jest tu aż taka istotna a to kto który konstruktor woła ;). Uruchom sobie przykład z tamtego tematu z finalizacją klasy i przekonasz się że działa to tylko dlatego że klasa pochodna woła próbuje wołać konstruktor wirtualnej klasy bazowej. Jeśli chodzi o źródło to musisz poszukać gdzieś w Stroustrupie albo w dokumentacji.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2012-01-20 16:54
0

Wydaje mi się, że było to źle wytłumaczone. Przed wywołaniem konstruktora wywoływane są po kolei wszystkie konstruktory klas bazowych w kolejności dziedziczenia. Pola w pamięci ułożone są identycznie jak wywoływane konstruktory. Dziedziczenie wirtualne pozwala na to, że jeżeli dana klasa jest już wcześniej w tej kolejce, to nie jest ona duplikowana.

W przypadku wspomnianego przykładu jeżeli pochodna2 dziedziczy wirtualnie po pochodnej1 oraz po bazowej, to będzie miała tylko jeden egzemplarz klasy bazowej. W przypadku normalnego dziedziczenia obydwie klasy bazowe istnieją osobno i mogą mieć pola o tej samej nazwie, ale o innych wartościach. Wprowadza to też dodatkową komplikację przy pisaniu kodu, nie mówiąc już o zrozumieniu.

Mogę się gdzieś mylić, bo już dawno nie stosowałem dziedziczenia wielokrotnego. Jest ono trochę podobne do goto, są przypadki gdzie zastosowanie tego może skutkować czytelniejszym kodem. Jednak w większości przypadków nie jest ono uzasadnione, nie stosowanie go zupełnie praktycznie nie ogranicza twoich możliwości.

edytowany 1x, ostatnio: Zjarek, 2012-01-20 17:04
Nie nie, absolutnie nie! Dziedziczenie wirtualne zaburza standardową wiązankę wywołania konstruktorów kaskadowo, co jest pokazane w kodzie w podlinkowanym temacie. - Shalom 2012-01-20 16:57
Rzeczywiście, sprawdziłem, sorry. http://ideone.com/dg1x1 - Zjarek 2012-01-20 17:02

Pozostało 580 znaków

2012-01-20 17:17
0

Prześledziłem kod który wstawił Azrael ileś razy za każdym razem z tym samym skutkiem, to nie jest tak, że powstają dodatkowe obiekty. Siedzę z powodu tamtego tematu od 2 dni w dokumentacji C++11 czytam i nigdzie nie mogę znaleźć odpowiedzi na to.
Przykład z dokumentacji:

struct V {};
struct A {};
struct B : A, virtual V {};
struct C : A, virtual V {};
struct D : B, C {};

Tutaj wszystko jest jasne, wywoływanie konstruktorów itp.
A V A
\ / \ /
B C
\ /
D

Natomiast w tamtym przypadku jest:
Final Final
\ /
MyFinal MyAlmostFinal
\ /
ImWrong ImWorking

Nie ma tu mowy o dwuznaczności.
Rozumiem to tak, skoro ImWorking wywołuje konstruktor MyAlmostFinal, a ten skolei jest zaprzyjaźniony z Final, to po prostu wywoła się tamten konstruktor klasy Final.
Problem jest ze zrozumieniem wirtualnego dziedziczenia MyFinal też jest zaprzyjaźniona, a mimo to, jej konstruktor nie wywoła konstruktora Final, tak jakby do tego konstruktora chciała się dostać klasa ImWrong bezpośrednio. Ale nigdzie w dokumentacji nie mogę znaleźć tego. Mimo tego dowiedziałem się z dokumentacji paru jeszcze ciekawych rzeczy o których nie wiedziałem, ale odpowiedzi na nurtujące mnie pytanie nie dostałem ;]


Gdy się nie wie, co się robi, to dzieją się takie rzeczy, że się nie wie, co się dzieje ;-)
Gdyby B nie dziedziczyło po V, to nadal V by było konstruowane jako pierwsze, chyba że zmieniłbyś dziedziczenie V przez C na niewirtualne. - Zjarek 2012-01-20 17:23
No teraz to sobie skojarzyłem, że klasa wirtualna jest zawsze konstruowana jako pierwsza ;-) dzięki. - MJay 2012-01-20 17:28

Pozostało 580 znaków

2012-01-20 17:27
0

prostytutka zczaiłem! A przynajmniej tak mi się wydaje.
Kiedy któraś z klas jest wirtualnie dziedziczona, to najpierw następuje sprawdzenie czy nie jest ona drugi raz konstruowana, stąd ImWrong przechodzi bezpośrednio do tamtego konstruktora i okazuje się, że jest niedostępny. Natomiast kiedy nie ma dziedziczenia wirtualnego to po prostu konstruktory są wywoływane w kolejności. Stąd to ominięcie "wężyka" ;] Jest w tym coś racji?


Gdy się nie wie, co się robi, to dzieją się takie rzeczy, że się nie wie, co się dzieje ;-)

Pozostało 580 znaków

Liczba odpowiedzi na stronę

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