#programowanie w #cpp - Dziedziczenie wirtualne Robiłem zadanie z Praty - konkretnie rozdział 14, zadanie 4, Język C++ Szkoła programowania wyd. 6 Mam jakąś klasę A jako bazową. Klasa B dziedziczy publicznie po A, klasa C dziedziczy publicznie wirtualnie po A. Klasa D dziedziczy publicznie po B i publicznie po C. Kompilator( MS VS Express 2013) nie dopuszcza do kompilacji takiego kodu wskazując na niejednoznaczność. Racja, są 2 obiekty klasy A w klasie D. Na liście inicjalizacyjnej klasy D jest wywołany konstruktor klasy A. Według książki jest wszystko ok, bo w klasach wirtualnych trzeba te konstruktory wywoływać jawnie. Wywołany jest też konstruktor klasy C, jednak jako, że dziedziczy wirtualnie po A to nie wywołuje jego konstruktora, więc tu nie powinno kolidować. Oczywiście rozwiązaniem jest dziedziczenie wirtualne klasy A przez klasę B. Wtedy wszystko działa. Jednak nie wiem jak zrobić, żeby w powyższym przypadku wszystko działało. Wirtualne destruktory są porobione, konstruktory też dla każdej z klas.
@Hrabia_Serek_von_Hochland: Linia 126: Nie rozumiem dlaczego chcesz inicjalizować klasę bazową która jest bazowa dla innej klasy z której dziedziczysz. Robisz tutaj coś dziwnego.
Rozwiązanie problemu to - albo tak mi się wydaje (jeśli nie usunięcie tej inicjalizacji):
BadDude::BadDude(string name, double time, int cuts) : ::Person(name), PokerPlayer(name), Gunslinger(name,time,cuts) {}
@psychob: Konstruktor klasy PokerPlayer nie inicjalizuje klasy Person właśnie. Jeśli dana klasa dziedziczy wirtualnie to trzeba jej klasę bazową inicjalizować oddzielnie. Tylko, że tu jest to mieszane i nie przechodzi. Kod:
BadDude::BadDude(string name, double time, int cuts) : PokerPlayer(name), Gunslinger(name,time,cuts) {} też nie przechodzi.
Person * p,q,r; p= new BadDude; q= new PokerPlayer; r = new Gunslinger; u Ciebie nie zadziała bo twoje dziedziczenie jest skopane, (czyli klasa bazowa person jest raz bazowa normalnie a raz wirtualnie) i kompilator nie wie którą z bazowych klas Person wybrać, dlatego ten: http://ideone.com/yrsCo7 przykład działa - bo powiedziałem kompilatorowi dokładnie na którą bazową klasę ma rzutować.
Jeśli chcesz by u Ciebie to zadziałało to musisz albo
@psychob: Dziedziczy z jednej Person, drugą wirtualnie dziedziczy przez PokerPlayer. BadDude ma dwie, co według książki jest dozwolone, jednak nie jest za bardzo wspomniane jak to właściwie robić. Treść zadania zakłada to co zrobiłem, jedynie nie precyzuje jak ma dziedziczyć klasę Person klasa Gunslinger, więc pewnie autorowi chodziło o dojście do tego, że trzeba użyć wirtualnego. Mnie tylko interesowało, czy da się zrobić tak, aby dziedziczyć 2 obiekty Person i to
@Hrabia_Serek_von_Hochland: No nie działa bo twoja hierarchia dziedziczenia jest bez sensu. Już wyżej Ci napisałem jak zrobić by działało to normalnie i jak to zrobić by działało to w twoim bezsensownym przypadku.
Robiłem zadanie z Praty - konkretnie rozdział 14, zadanie 4, Język C++ Szkoła programowania wyd. 6
Mam jakąś klasę A jako bazową. Klasa B dziedziczy publicznie po A, klasa C dziedziczy publicznie wirtualnie po A. Klasa D dziedziczy publicznie po B i publicznie po C. Kompilator( MS VS Express 2013) nie dopuszcza do kompilacji takiego kodu wskazując na niejednoznaczność. Racja, są 2 obiekty klasy A w klasie D. Na liście inicjalizacyjnej klasy D jest wywołany konstruktor klasy A. Według książki jest wszystko ok, bo w klasach wirtualnych trzeba te konstruktory wywoływać jawnie. Wywołany jest też konstruktor klasy C, jednak jako, że dziedziczy wirtualnie po A to nie wywołuje jego konstruktora, więc tu nie powinno kolidować.
Oczywiście rozwiązaniem jest dziedziczenie wirtualne klasy A przez klasę B. Wtedy wszystko działa. Jednak nie wiem jak zrobić, żeby w powyższym przypadku wszystko działało. Wirtualne destruktory są porobione, konstruktory też dla każdej z klas.
@Hrabia_Serek_von_Hochland: U mnie działa
źródło: comment_8ygbfvmGkpdguk19sSLZheyJsmlKLX4V.jpg
PobierzU mnie tak to wygląda i się nie kompiluje:
http://pastebin.com/x73P7DLv
Rozwiązanie problemu to - albo tak mi się wydaje (jeśli nie usunięcie tej inicjalizacji):
BadDude::BadDude(string name, double time, int cuts) : ::Person(name), PokerPlayer(name), Gunslinger(name,time,cuts) {}Kod:
BadDude::BadDude(string name, double time, int cuts) : PokerPlayer(name), Gunslinger(name,time,cuts) {}też nie przechodzi.
@Hrabia_Serek_von_Hochland: Hmm, tego nie wiedziałem... Człowiek uczy się całe życie, ale wydaje mi się to że rozwiązanie zadziała:
BadDude::BadDude(string name, double time, int cuts) : PokerPlayer::Person(name), PokerPlayer(name), Gunslinger(name,time,cuts) {}Ale głowy nie dam
Person * p,q,r;p= new BadDude;
q= new PokerPlayer;
r = new Gunslinger;
Person * p,q,r;p= new BadDude;
q= new PokerPlayer;
r = new Gunslinger;
u Ciebie nie zadziała bo twoje dziedziczenie jest skopane, (czyli klasa bazowa person jest raz bazowa normalnie a raz wirtualnie) i kompilator nie wie którą z bazowych klas Person wybrać, dlatego ten: http://ideone.com/yrsCo7 przykład działa - bo powiedziałem kompilatorowi dokładnie na którą bazową klasę ma rzutować.
Jeśli chcesz by u Ciebie to zadziałało to musisz albo
@Hrabia_Serek_von_Hochland: Przecież działa, pokazałem Ci kod w którym twój dziwny przypadek - który notabene nie ma wcale sensu - działa.