world007 Temat założony przez niniejszego użytkownika |
Dziedziczenie wielokrotne » 2007-12-14 23:48:46 Mam otóż taki problem. jest funkcja: #include <iostream.h> class A { public: int a; }; class C : public A { public: int c; }; class B : public A { public: int b; }; class D : public B , public C { public: int d; }; int main() { D Obiekt; cout << "Skladowa a od klasy B: " << Obiekt.B::a << endl; cout << "Skladowa a od klasy C: " << Obiekt.C::a << endl; return 0; } B i C dziedziczą po A, a D dziedziczy po B i C. I takie odwołania: Obiekt.B::a i Obiekt.C::a, niby tyczą się tej samej zmiennej a, jednak wyświetlane są inne wyniki, tak jakby kompilator robił 2 kopie zmiennej a, które są dostępne z klasy D (jak by istniały dwie zmienne a) Moje pytanie brzmi, dlaczego tak się dzieje i jak dostać się do zmiennych z klasy A, bezpośrednio z klasy D nie używając jednak wirtualizacji ani wskaźników (żeby zmienna a była jednoznaczna).Jak także można się dostać, do zmiennej X w takiej funkcji (nie używając oczywiści funkcji wirtualnych ani wskaźników):class X { public: int x; }; class A : public X { public: int a; }; class C : public A { public: int c; }; class B : public A { public: int b; }; class D : public B , public C { public: int d; int main() { D Obiekt; return 0; }; Nigdzie nie znalazłem odpowiedzi na te pytanie (ani w książkach, ani w internecie), więc był bym wdzięczny za pomoc jakiegoś doświadczonego programisty. |
|
DejaVu |
» 2007-12-15 12:24:33 [tutorial] [li]Klasa B dziedziczy po klasie A, więc klasa B ma interfejs klasy A i B.[/li] [li]Klasa C dziedziczy po klasie A, więc klasa C ma interfejs klasy A i C.[/li] [li]Klasa D dziedziczy po klasie B i C, więc ma interfejs klasy B i C i D. Ponieważ interfejs B i C dziedziczą po klasie A, to klasa D ma w konsekwencji interfejsy: (A+B) i (A+C) i (D). [/li] To jest normalna i prawidłowa własność dziedziczenia. Ty chciałbyś osiągnąć taki stan, że otrzymujesz wspólną zmienną a, która po dziedziczeniu należy osobno do klasy B i C, co jest fizycznie niemożliwe. Skąd kompilator ma wiedzieć, która zmienna jest prawidłowa na poziomie klasy D? Moim zdaniem jedyne co możesz zrobić w tym wypadku to utworzyć z klasie D zmienną int &a; i zainicjować ją tak, aby wskazywała na zmienną z interfejsu klasy B lub C. Szczegóły wykorzystania zapisu int &a; znajdziesz w rozdziale: http://ddt.pl/kursy/?LessonId=131Aby dostać się do zmiennej w X, piszesz: cout << Obiekt::B::A::X::x; [/tutorial] |
|
world007 Temat założony przez niniejszego użytkownika |
» 2007-12-15 14:31:30 cout<<Obiekt::B::A::X::x; Niestety ten sposób nie działa.
Można do zmiennej x dostać się w taki sposób: cout<<Obiekt.B::x; Jednak to nie jest jednoznaczne, jak już napisałeś.
Ale jak się dostać powiedzmy do zmiennych z najstarszej klasy, z klasy najmłodszej, jeśli w dziedziczeniach występuje kilka "rozgałęzień", jak przez nie przejść jednoznacznie.
ps. Wiem że to wydumany problem, bo można po prostu użyć dziedziczenia wirtualnego, jednak na zajęciach wykładowca dał nam właśnie taki problem do rozwiązania. (ciekawe czy wogóle da się to jakoś rozwiązać, czy to tylko podpucha z jego strony)
|
|
world007 Temat założony przez niniejszego użytkownika |
» 2007-12-15 14:31:34 //sorki za dwa posty
|
|
DejaVu |
» 2007-12-15 14:50:01 [tutorial]wewnątrz klasy D możesz użyć chyba zapisu cout<<__super::a; lub cout<<__super->a; ale w momencie gdy dziedziszysz równolegle dwie klasy, to i tak nie będzie jednoznaczności, więc będziesz musiał podać ::B lub ::C.
__super działa chyba tylko pod visual studio. [/tutorial] |
|
world007 Temat założony przez niniejszego użytkownika |
» 2007-12-15 23:53:18 ok, dzięki
tak więc nie jest to takie łatwe, powiem wykładowcy, że nie znalazłem tego czego chce, może mi powie o co mu chodziło :) |
|
DejaVu |
» 2007-12-16 11:47:57 Jak będziesz miał odpowiedź od wykładowcy to napisz nam na forum :) Sam jestem bardzo ciekaw :) Może chodzi o dopisanie jakiegoś słowa kluczowego przy dziedziczeniu, skoro mówisz że wykładowca coś takiego wymyślił i mówi że się da... |
|
DejaVu |
» 2007-12-16 12:04:51 Bez wykorzystania słowa kluczowego virtual nie wiem jak to zrobić. #include <iostream> using namespace std; #include <conio.h>
class A { public: int a; }; class C : virtual public A { public: int c; }; class B : virtual public A { public: int b; }; class D : public B , public C { public: int d; }; int main() { D Obiekt; Obiekt.B::a = 999; cout << "Skladowa a od klasy B: " << Obiekt.B::a << endl; cout << "Skladowa a od klasy C: " << Obiekt.C::a << endl; Obiekt.B::a = 132; cout << "Skladowa a od klasy B: " << Obiekt.B::a << endl; cout << "Skladowa a od klasy C: " << Obiekt.C::a << endl; getch(); return 0; } |
|
« 1 » 2 |