Kaikso Temat założony przez niniejszego użytkownika |
Oddzielanie klas dziedziczących wirtualnie. » 2015-07-25 01:30:55 class Bazowa_A; class Bazowa_B; class Bazowa_C;
class Pochodna_AB : virtual public Bazowa_A , virtual public Bazowa_B;
class Pochodna_AC : virtual public Bazowa_A , virtual public Bazowa_C;
class Pochodna_BC : virtual public Bazowa_B , virtual public Bazowa_C;
class Pochodna_AB_BC : virtual public Pochodna_AB , virtual public Pochodna_AC;
class Klasa_X final : public Pochodna_BC , public Pochodna_AB_BC;
Uwaga! Wszystkie klasy bazowe pochodzą z zewnętrznej biblioteki, na którą ja nie mam wpływu. |
A więc potrzebuję stworzyć klasę, która dziedziczy niewirtualnie po dwóch klasach. Niestety te klasy przez owe dziedziczenie wirtualne wchodzą w konflikt. Jeśli ktoś zna jakąś sztuczkę na oddzielenie składowych klas bazowych od siebie nawzajem, to proszę o sugestię. @Edit: Tak chyba czytelniej. |
|
notabigthreat |
» 2015-07-25 01:43:24 A dlaczego potrzebujesz dziedziczyć niewirtualnie? |
|
Kaikso Temat założony przez niniejszego użytkownika |
» 2015-07-25 01:49:14 @Up: Wyżej jest wytłumaczone. Klasy bazowe wchodzą nawzajem w konflikt, z powodu wspólnych klas bazowych najwyższego poziomu. |
|
Monika90 |
» 2015-07-25 10:24:07 Klasa_X w ogóle nie zależy od klasy Pochodna_BC. Po co więc pokazujesz nam Pochodna_BC? |
|
Kaikso Temat założony przez niniejszego użytkownika |
» 2015-07-25 12:33:57 Mój błąd, schemat kodu miał wyglądać nieco inaczej. Ale to niczego nie zmienia i wciąż oddaje istotę problemu.
@Edit: Poprawiłem kod. |
|
Monika90 |
» 2015-07-25 13:57:38 Nie wiem o jakim problemie mówisz. W twoim kodzie każda klasa podstawowa klasy Klasa_X ma jednoznaczną ścieżkę dostępu. class Bazowa_A { }; class Bazowa_B { }; class Bazowa_C { };
class Pochodna_AB : virtual public Bazowa_A , virtual public Bazowa_B { };
class Pochodna_AC : virtual public Bazowa_A , virtual public Bazowa_C { };
class Pochodna_BC : virtual public Bazowa_B , virtual public Bazowa_C { };
class Pochodna_AB_BC : virtual public Pochodna_AB , virtual public Pochodna_AC { };
class Klasa_X final : public Pochodna_BC , public Pochodna_AB_BC { };
int main() { Klasa_X x; Bazowa_A * p1 = & x; Bazowa_B * p2 = & x; Bazowa_C * p3 = & x; Pochodna_AB * p4 = & x; Pochodna_AC * p5 = & x; Pochodna_BC * p6 = & x; Pochodna_AB_BC * p7 = & x; }
Kompilator też nie widzi problemu. |
|
Kaikso Temat założony przez niniejszego użytkownika |
» 2015-07-25 14:45:06 Tu chodzi o błąd w czasie wykonania. #include <iostream>
struct Bazowa_A { int a; }; struct Bazowa_B { int b; }; struct Bazowa_C { int c; };
class Pochodna_AB : virtual public Bazowa_A , virtual public Bazowa_B { };
class Pochodna_AC : virtual public Bazowa_A , virtual public Bazowa_C { };
class Pochodna_BC : virtual public Bazowa_B , virtual public Bazowa_C { public: Pochodna_BC( int b, int c ) { this->b = b; this->c = c; } virtual void test_bc() { std::cout << "----- test_bc() ------" << std::endl; std::cout << "b = " << b << std::endl; std::cout << "c = " << c << std::endl; } };
class Pochodna_AB_BC : virtual public Pochodna_AB , virtual public Pochodna_AC { public: Pochodna_AB_BC( int a, int b, int c ) { this->a = a; this->b = b; this->c = c; } };
class Klasa_X final : public Pochodna_BC , public Pochodna_AB_BC { public: Klasa_X() : Pochodna_BC( 0, 1 ) , Pochodna_AB_BC( 2, 3, 4 ) { } };
int main() { Klasa_X x; x.test_bc(); return 0; }
Oczekiwany wynik: ----- test_bc() ------ b = 0; c = 1;
Prawdziwy wynik: ----- test_bc() ------ b = 3; c = 4;
A teraz wyobraźcie sobie, że to są np. wskaźniki do świeżo zaalokowanych obiektów. Efekt gwarantowany crash aplikacji. |
|
jankowalski25 |
» 2015-07-25 15:17:00 [Wikipedia] Lista_inicjalizacyjna_konstruktoraKolejność wywołań konstruktorów klasy bazowej czy też obiektów składowych jest ściśle określona (zobacz: konstruktor) i nie jest ważna kolejność w jakiej zostaną napisane wywołania konstruktorów klas bazowych na liście inicjalizacyjnej. |
Konstruktory klas bazowych w kolejności w jakiej znajdują się w sekcji dziedziczenia w deklaracji klasy pochodnej. |
|
|
« 1 » 2 3 |