Wielodziedziczenie i wieloznaczność składowych

0

Zrobiłem sobie eksperyment podczas wielodziedziczenia usuwając przy deklaracjach klas które były dziedziczone słowo kluczowe virtual, które rozwiązywało problem wieloznaczności składowych.
Hierarchia klas wygląda następująco: Klasy Animal() i Human() dziedziczą po klasie Mammal skolei Mammal dziedziczy po klasie abstrakcyjnej Proper, która pełni funkcję interfejsu.

I teraz zaczyna się problem, o ile kiedy Animal i Human były dziedziczone jako klasy virtualne było wszystko OK to teraz wygląda to tak, że nie mogę utworzyć instancji klasy Muntant, która wielodziedziczy po Animal() i Human() :

Mammal* xmen = new Mutant();

Tak nie przejdzie, gdyż dochodzi do wieloznaczności, ok rozwiązałem to przez rzutowanie do jednej z klas Animal() lub Human():

Mammal* xmen = (Animal *)new Mutant();

Jest ok, ale przez to tracę możliwość dostania się bezpośrednio do metod i właściwości zdefiniowanych w Mutant, pozostają tylko te odziedziczone.
No więc aby kompilator się nie burzył zrobiłem kolejne rzutowanie:

dynamic_cast<Mutant *>(xmen)->metodaMutanta()

No cóż jeśli inaczej się tego nie da rozwiązać to nie dziwię się, że wielodziedziczenie w takiej formie nie jest zbytnio dobrze oceniane.
Pozostaje używać wielodziedziczenia wirtualnego albo robić sobie tego typu komplikacje bo innej sytuacji tutaj nie widzę, chodzi o te nieszczęsne rzutowanie na Animal* lub Human* ( czyli klasy o szczebel niżej - tracąc przy tym dostęp do składowych utworzonych o szczebel wyżej ) chyba, że coś przeoczyłem ?

3

No ale to tak ma działać przecież. Najlepiej to nie robić tego typu "diamentowego" wielodziedziczenia, czyli zwyczajnie przeprojektować hierarchię klas.
Ale jak musi tak być, to do tego służy właśnie dziedziczenie wirtualne.

0

No tak jak napisałem z uwagi na to iż Human i Animal dziedziczyły po wspólnej klasie automatycznie zadeklarowałem dziedziczenie wirtualne. I wtedy wszystko działało jak należy. Czyli dochodzę do wniosku, że drugie "eksperymentalne" podejście to jego zastosowanie jest wyjątkowo niszowe. Na pewno przy mojej hierarchii klas jedynie słusznym dziedziczeniem jest wielodziedziczenie wirtualne. Druga wersja to bardziej sztuka dla sztuki.

3

Na pewno przy mojej hierarchii klas jedynie słusznym dziedziczeniem jest wielodziedziczenie wirtualne.

Na pewno nie jest. Wielodziedziczenie prawie nigdy nie jest słusznym rozwiązaniem, a "jedynym" nie jest nigdy. Kompozycja z delegacją > wielodziedziczenie. Czemu Mutant nie będzie po prostu miał w sobie człowieka i zwierzaka i jedynie implementował interfejs obu?

0

Oczywiście, że tak można co nie zmienia faktu, że akurat C++ dopuszcza wielodziedziczenie i są też osobnicy dla których jest to bardzo poważny atut tego języka.
W Objective C to właśnie robiło się tak jak napisałeś, w JAVIE też nie ma wielodziedziczenia ale są interfejsy. Z wszystkich języków z którymi miałem do czynienia to tylko C++ daje wielodziedziczenie inna sprawa, że moje doświadczenie w przypadku wielodziedziczenia za duże nie jest a i stosowanie go dla mnie póki co jest tak jak napisałem sztuką dla sztuki. Właśnie przez te kombinacje z niejednoznacznością jeśli nie dziedziczymy po klasach wirtualnych. Tak więc wg mnie można się bez tego obyć ale rozumiem, że są ludzie dla których takie podejście jest grzechem ;)

1

W Javie i C# masz intefejsy, w C++ masz klasy w abstrakcyjne, które de facto spełniają tę samą rolę i głównie po to jest wielodziedziczenie ;)

0

Dlatego napisalem ze c++ jako jedyny ze znanych mi jezykow daje mozliwosc faktycznego wielodziedziczenka oczywiscie klasa abstrakcyjna z czysto wirtualnymi metodami spelnia role interfejsu ale sama konstrukcja jezyka w tym elemencie nie ogranicza programisty do samego interfejsu mozna zrobic mieszanie glowna klasa to interfejs pozostale klasy wspolnie dziedzicza ten interfejs dzieki czemu dziala polimorfizm a do tego z tych klas mozna utworzyc klase wielodziedziczaca jedno nie wyklucza drugiego. Inna sprawa ze moze komplikowac strukture zaleznosc klas no ale cos w tym jest poznasz c++ to nie bedziesz mial zadnych problemow z java czy obj c lub podobnymi :) gdyz same sa ubozsze i okrojone tylko do tego cof aktycznie jest potrzebne jakiemus lajtowemu programiscie :)

0

To juz trzeba sie Strousupa zapytac ;)

0

Cholerka niezalogowalem sie i zostalem krzywym mlotem lol ;)

1

jedno z rozwiązań to dziedziczenie wirtualne:
http://ideone.com/LriLzi
http://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem

Ale jak pisał Shalom to rozwiązanie od strony projektowej najczęściej jest do bani.

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