Vererbung & Template
-
Hallo!
Ich hab ein kleines Verständnisproblem was das Vererben angeht
Ich habe 3 Klassen, nennen wir sie "Futter", "Kopf" und "Body". "Kopf" erbt von "Body".
Zusätzlich habe ich das Beobachter Entwurfsmuster von http://www.codeproject.com/cpp/observer_with_templates.asp.
Nun mein Problem:
Damit das mit dem Entwurfsmuster funktioniert, erbt "Body" noch "Subject" (public Subject<Body>) und "Futter" zusätzlich noch "Observer" (public Observer<Head>).
Für mein Verständnis sollte es funktionieren, denn "Head" ist doch durch die Vererbung auch "Body", trotzdem funktioniert das "public Observer<Head>" nicht. Wenn ich hier statt "Head" "Body" benutze, dann läuft es, ich bräuchte hier aber "Head".Wo ist mein Fehler?
Danke! Ralph
#include <iostream.h> #include <conio.h> #include <vector.h> template <class T> class Observer { public: Observer() {} virtual ~Observer() {} virtual void update(T *subject)= 0; }; template <class T> class Subject { public: Subject() {} virtual ~Subject() {} void attach (Observer<T> &observer) { m_observers.push_back(&observer); } void notify () { std::vector<Observer<T> *>::iterator it; for (it=m_observers.begin();it!=m_observers.end();it++) (*it)->update(static_cast<T *>(this)); } private: std::vector<Observer<T> *> m_observers; }; class Body : public Observer<Body>, public Subject<Body> { public: void update(Body *subject) {}; }; class Futter; class Head : public Observer<Futter>, public Body { public: void update(Futter *subject) {}; }; class Futter : public Observer<Head>, public Subject<Futter> { public: void update(Head *subject) {}; }; int main() { Head head; Futter futter; head.attach(futter); futter.attach(head); getch(); return (0); }
[C++ Warnung] muster.cpp(40): W8022 'Head::update(Futter *)' verbirgt virtuelle Funktion 'Body::update(Body *)'. [C++ Warnung] muster.cpp(54): W8030 Temporäre Größe für Parameter 'observer' in Aufruf von 'Subject<Body>::attach(Observer<Body> &)' verwendet [C++ Fehler] muster.cpp(54): E2064 'Observer<Body> &' kann nicht mit 'Futter' initialisiert werden. [C++ Fehler] muster.cpp(54): E2342 Keine Übereinstimmung des Typs beim Parameter 'observer' ('Observer<Body> &' erwartet, 'Futter' erhalten)
-
Ein Blick auf die Meldungen im Detail:
[C++ Warnung] muster.cpp(40): W8022 'Head::update(Futter *)' verbirgt virtuelle Funktion 'Body::update(Body *)'.
Hier haben wir zunächst die Unschönheit, das Ableitungen neuer Observer von bestehenden Observer-Typen deren virtuelle update-Methode verdecken, weil sie einen anderen Typ haben. (Warum ist Body ein Observer<Body>?)
[C++ Fehler] muster.cpp(54): E2064 'Observer<Body> &' kann nicht mit 'Futter' initialisiert werden.
[C++ Fehler] muster.cpp(54): E2342 Keine Übereinstimmung des Typs beim Parameter 'observer' ('Observer<Body> &' erwartet, 'Futter' erhalten)Tja, es wird head.attach(futter); versucht, aber head ist ein Subject<Body> und kein Subject<Head>, also kann sich nur ein Observer<Body> attachen, futter ist aber ein Observer<Head>. (Es werden zwar u.U. Objekte, aber keine Typen gecastet, darum ist ein Observer<Head> keineswegs kompatibel mit einem Observer<Body>, auch wenn ein Head ein Body ist
)
-
in so einem Fall wäre vermutlich ein Zeigerbasiertes Beobachtermuster angemessener. Das würde nämlich genau das Problem beheben...
-
pumuckl schrieb:
in so einem Fall wäre vermutlich ein Zeigerbasiertes Beobachtermuster angemessener. Das würde nämlich genau das Problem beheben...
hmmm... Du hast nicht zufällig einen Link für mich, wo ich mir dies anschauen kann?
Ralph