Diamentowy problem i dziedziczenie wirtualne

Język C++ oferuje możliwość dziedziczenia wielokrotnego ze wszystkimi wadami i zaletami tego rozwiązania. W przypadku dziedziczenia po kilku klasach mających wspólnego przodka może pojawić się problem z diamentem.

Błąd „base class is ambiguous” świadczy o tym, że dwie klasy, po których dziedziczy nasza „najmłodsza klasa” są potomkami wspólnego przodka. Jeśli obie te klasy dziedziczą po tym przodku niewirtualnie to otrzymamy wspomniany wcześniej błąd, ponieważ klasa dziadka zostanie dodana dwa razy, więc będzie zduplikowana. Rozwiązaniem problemu będzie zastosowane dziedziczenia wirtualnego w naszych dwóch klasach.

W moim projekcie dziedziczenie wirtualne zostało zastosowane przy dziedziczeniu podstawowej klasy pola – RootField. Klasa RootField przechowuje tylko główne, wspólne parametry pola takie jak szerokość i wysokość. Następnie mamy dwie klasy po niej dziedziczące – DrawingAreaField oraz BlocksDescriptionField. Jeden dostarcza metody dla obszaru rysowania (DrawingArea) a drugi dla opisów bloków (RowsDescription i ColumnsDescription). Klasa WholeField łączy te elementy w całość i pozwala odwoływać się do pola roboczego jako całości, np. z poziomu solvera.

Kolejnym problemem okazało się wywoływanie konstruktorów parametrycznych z klasy bazowej (dziedziczonej wirtualnie) za pomocą listy inicjalizacyjnej. Okazało się, że wywołanie konstruktora klasy bazowej (dziedziczonej wirtualnie) za pomocą listy inicjalizacyjnej musi znajdować się w najmłodszej klasie – w tej, której obiekt zostanie utworzony za pomocą konstruktora parametrycznego. W sytuacji gdy mamy hierarchię klas, np:

Linki na temat:
multiple-inheritance-from-two-derived-classes
how-can-i-avoid-the-diamond-of-death-when-using-multiple-inheritance
Multiple_inheritance#The_diamond_problem
Virtual_inheritance

Wywoływanie konstruktorów z klasy wirtualnie dziedziczonej za pomocą listy inicjalizacyjnej.
order-of-constructor-call-in-virtual-inheritance

Dodaj komentarz

Twój adres email nie zostanie opublikowany.