Dziedziczenie wirtualne - skutki

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?

0

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

1

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.

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.

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 ;]

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?

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