2008-12-13 13 views

Odpowiedz

27

Powszechnym problemem z wielokrotne dziedziczenie jest „problem diament”.

A 
/\ 
B c 
\/
    D 

Jeśli wirtualna metoda w A jest zaimplementowana zarówno przez B, jak i C, którą otrzymasz podczas tworzenia D?

Przyczyną tego nie jest problem z interfejsami, ponieważ interfejsy nie mają implementacji, więc jeśli A/B/C są wszystkimi interfejsami, to D wybiera sposób implementacji metod A w dowolny sposób.

+2

To nie jest problem, jeśli potrzebujesz D do dwuznaczności. –

2

Jak godzisz jeśli A implementuje metodę zwaną oo oraz b implementuje metodę nazywa się Z i masz:

dziecko: a, b

teraz, jeśli mój kod klienta wywołuje nowe dziecko(). Z(). Którą implementację nazywa się? Nie sądzę, że jest tak dużo, jak to tylko jego zło rodzi mnóstwo lepkich punktów i zapewnia małą wartość

+0

Ten problem można łatwo rozwiązać, jeśli kompilator wymaga zastąpienia metody z w klasie potomnej. Ten sam problem występuje również w językach, w których dziedziczenie wielu interfejsów jest dozwolone, jeśli masz 2 interfejsy z metodą o tej samej nazwie, ale o innym sygnaturze. – hariseldon78

3

MI to nie tyle zło, co bardzo złożone rozwiązanie rzadkiego problemu. W większości przypadków jest lepszy sposób na zrobienie tego samego.

13

Jest postrzegany jako zło, bo to po prostu bardziej skomplikowane i stwarza więcej problemów niż ludzie zwykle się spodziewać, zwłaszcza w przypadku klasy bazowe nie są czysto abstrakcyjne (brak danych użytkowników). Dziedziczenie diamentów można rozwiązać za pomocą dziedziczenia wirtualnego, w którym wspólna baza jest współużytkowana. Kompilatory mogą przechwytywać kolizje sygnatur metod. Dobrze wykorzystane, może produkować eleganckie i SUCHE rozwiązania, które w przeciwnym razie są bardziej szczegółowe do wdrożenia poprzez interfejs i kompozycje/delegacje.

Jeden wspólny idiom MI w C++ jest dla złożonych konstruktorów, w których bazowy contructor musi być skonstruowany z nietrywialnymi obiektami członkowskimi, a ponieważ obiekty bazowe muszą być skonstruowane przed obiektami członka, sztuczka polega na użyciu MI (" opiera się na "idiomie" członka.) W przeciwnym razie musisz użyć fabryki i wykonać więcej kroków, aby wykonać taką konstrukcję jak Java (Java nie ma MI dla klas nieinterfejsowych).

Nie bój się tego i używaj go w razie potrzeby (choć może to zająć trochę praktyki, aby wykryć dobre dopasowanie).

Powiązane problemy