Dziedziczenie - wykładniczy rozrost klas

0

Hej,
Mam daną klasę A, która zawiera puste metody (ma definicje ale są puste):

claas A
{
public:
  virtual void test1() {}
  virtual void test2() {}
};

Oraz klasę B, która dziedziczy po A i nadpisuje metodę test1:

class B : public A
{
public:
  void test1() override {...}
};

I teraz mam kolejną klasę, która napisuję metodę test2. Klasy C i B nie wykluczają się. Taka klasa C powinna rozszerzyć zatem klasę A ale i B. Mamy już 4 kombinacje. Dojdzie kolejną klasa, będzie 9 kombinacji.
Liczba plików rośnie wykładniczo.

Jakiś pomysł jak to zrobić dynamicznie? Myślałem nad szablonem ale definicja klas koniecznie musi znajdować się w odosobnionym pliku .cpp oraz muszę mieć decyzje, które klasy mogą rozszerzać podrzędne.

5

Taka klasa C powinna rozszerzyć zatem klasę A ale i B

? Po co Ci dziedziczenie z B?

To mi wyglada jakbys naduzywal dziedziczenia. Na pewno nie chcesz / nie mozesz uzyc tutaj kompozycji?

5

Dobra z a teraz zamiast A, B i C napisz konkretnie jakiś życiowy przykład. Poza tym twoja klasa A wygląda na złamanie zasady separacji interfejsów i zasady podstawiania, skoro robisz klasę B która dziedziczy z A i nie nadpisuje wszystkich metod czysto wirtualnych. To ci kiedyś wybuchnie w twarz, bo ktoś zawoła sobie tą metodę.
Szklana kula mówi że powinienes mieć 2 osobne interfejsy, jeden z metodą test1 a drugi z test2.

1

Btw, zamiast pustych metod zrób je czysto wirtualne.

1
Focusx napisał(a):

I teraz mam kolejną klasę, która napisuję metodę test2. Klasy C i B nie wykluczają się. Taka klasa C powinna rozszerzyć zatem klasę A ale i B. Mamy już 4 kombinacje.
Dojdzie kolejną klasa, będzie 9 kombinacji.

Jakie kombinacje?

1
Focusx napisał(a):

Liczba plików rośnie wykładniczo.

W jaki sposób?

1

Z tego co napisałeś wynika, że to powinny być osobne interfejsy jak napisał Shalom. Jeżeli z jakiegoś powodu, którego nam nie podałeś, to nie mogą być osobne interfejsy, to robisz kompozycje jak napisał fasadin.
Ewentualnie mixiny, ale to zależy co dokładnie chcesz osiągnąć.
Dziedziczenie diamentowe, które próbujesz zrobić nie jest zbyt często spotykane w praktyce.

PS. Wygląda to na złe zrozumienie programowania obiektowego i nadużywania dziedziczenia.

0

Przykład z życia (związany z OpenGL).
Klasa bazowa to obiekt 3d. Taka klasa zawiera macierz transformacji, mesh oraz shadery. Klasa dziedzicząca po niej to object3dInstanced - jedna metoda renderująca kilka obiektów na raz, z tym samym meshem (nieco zmienia jej definicje), nieco inne shadery.

Klasa bazowa (Object3d) zawiera również pustą definicje metody "void update()", która jest zawsze wywoływana w metodzie render().
Tu pojawia się klasa C, czyli SkinnedObject3d. Taka klasa może dziedziczyć po Object3d lub po object3dInstanced. Nadpisuje ona bowiem wyłącznie metodę update(). Shadery chcę zrobić by generowały się dynamicznie w zależności jaką mamy klasę nadrzędną.

Po co tak? Czemu nie używam zwykłego if'a?
A no dlatego, że do animacji obiektu pojawi się wiele nowych pól, które są zbędne dla obiektu statycznego (bez animacji szkieletowej).

Planem awaryjnym jest utworzenie wektora w klasie Object3d, który będzie zawierał dedykowane dla niej komponenty. Jak dla mnie to mniej przejrzyste będzie.

1

Mi to wygląda na książkowy przykład na wzorzec Composite.

0

W zasadzie może faktycznie Kompozyt będzie najlepszy.
Dzięki za podpowiedzi.

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