Istnieje wiele problemów z wielokrotnym dziedziczeniem, gdy jest ono używane z pełnoprawnymi klasami, ale wszystkie dotyczą niejednoznaczności .
Dwuznaczność ujawnia się na kilka różnych sposobów:
- Jeśli masz dwie klasy podstawowe z tym samym polem
x
, a typ pochodny pyta o x
to, co on otrzymuje?
- Jeśli dwie
x
zmienne mają niespójne typy, możesz je wywnioskować.
- Jeśli są tego samego typu, możesz spróbować połączyć je w tę samą zmienną.
- Zawsze możesz je ujawnić jako dziwne, w pełni kwalifikowane nazwy.
- Jeśli masz dwie klasy podstawowe z tą samą funkcją
f
i identycznymi podpisami, a ktoś dzwoni f
, który zostaje wywołany?
- Co jeśli dwie klasy podstawowe mają wspólnego wspólnego wirtualnego przodka (problem z diamentem).
- Co jeśli funkcja ma inne, ale kompatybilne podpisy?
- Kiedy konstruujesz klasę z dwiema klasami podstawowymi, który z konstruktorów klas podstawowych jest nazywany pierwszy? Kiedy niszczysz obiekt, który zostaje zabity?
- Jak konsekwentnie układasz obiekt w pamięci?
- Jak poradzisz sobie z tymi wszystkimi przypadkami z 3 klasami podstawowymi? 10?
I to ignoruje takie rzeczy jak dynamiczne wysyłanie, wnioskowanie o typie, dopasowywanie wzorców i inne rzeczy, o których mniej wiem, które stają się trudniejsze, gdy język obsługuje wielokrotne dziedziczenie pełnych klas.
Cechy lub wtyczki (lub interfejsy lub ...) to konstrukcje, które konkretnie ograniczają możliwości danego typu, dzięki czemu nie ma dwuznaczności. Rzadko są właścicielami czegokolwiek. Pozwala to na płynniejszą kompozycję typów, ponieważ nie ma dwóch zmiennych lub dwóch funkcji ... istnieje zmienna i odwołanie; funkcja i podpis. Kompilator wie, co robić.
Innym powszechnie stosowanym podejściem jest zmuszanie użytkownika do „budowania” (lub mieszania) swojego typu pojedynczo. Zamiast klas podstawowych będących równorzędnymi partnerami w nowym typie, dodajesz jeden typ do drugiego - zastępując wszystko, co tam było (zwykle z opcjonalną składnią, aby zmienić nazwę i / lub ponownie ujawnić przesłonięte bity).
Czy jest coś, co nie jest możliwe w przypadku mixin / cech, ale jest możliwe w przypadku wielokrotnego dziedziczenia w stylu C ++?
W zależności od języka - na ogół staje się kłopotliwe lub niemożliwe do scalenia implementacji funkcji i pamięci dla zmiennych z wielu klas bazowych i ujawnienia ich w typie pochodnym.
Czy można z nimi spotkać problem z diamentem?
Czasami pojawiają się mniej poważne odmiany w zależności od języka, ale zwykle nie. Cały sens cech polega na przełamaniu tego rodzaju dwuznaczności.