ein polymorphes Problem
-
Hallo.
Ich hab ein schwer zu ergoogelndes Problem mit Polymorphie. Vielleicht kann mir jemand weiterhelfen. Folgender Beispiel-Code:
#include <iostream> using namespace std; class Data { public: virtual ~Data() {} int x; }; class Verifier { public: virtual bool verify(Data* d) = 0; }; class specialData : public Data { public: int y; }; class specialVerifierA : public Verifier { public: bool verify(Data* d) { cout << ":-/ specialVerifierA "<< d->x <<" >= 0 ?"<<endl; return (d -> x >= 0); } bool verify(specialData* s) { cout << ":-) specialVerifierA "<< s->x <<" >= 0 && " << s->y << " >= 0 ?"<<endl; return (s -> x >= 0 && s -> y >= 0); } }; class specialVerifierB : public Verifier { public: bool verify(Data* d) { cout << ":-/ specialVerifierB "<< d->x <<" < 100 ?"<<endl; return (d -> x < 100); } bool verify(specialData* s) { cout << ":-) specialVerifierB "<< s->x <<" < 100 && " << s->y << " < 100 ?"<<endl; return (s -> x < 100 && s -> y < 100); } }; class Checker { private: Verifier* v; Verifier* w; public: Checker(Verifier* vv, Verifier* ww) {v = vv; w = ww;} bool check(Data* d) { specialData* s = dynamic_cast<specialData*>(d); if(s) { cout << "checking specialData" << endl; return (v -> verify(s) && w -> verify(s)); } else { cout << "checking Data" << endl; return (v -> verify(d) && w -> verify(d)); } } }; int main() { specialVerifierA A; specialVerifierB B; Checker C(&A, &B); specialData S; S.x = 23; S.y = 42; cout << ( C.check(&S) ? "jo" : "ne" ) << endl; return 0; }Die Ausgabe ist:
checking specialData :-/ specialVerifierA 23 >= 0 ? :-/ specialVerifierB 23 < 100 ? joDas bedeutet, er ruft beim
checken immer dieverify(Data* d)auf. Ich hätte aber gern, dass er dieverify(specialData* s)aufruft - immerhin ist das zu-verifyende Objekt ja vom TypspecialData, wie die erste Zeile der Ausgabe verlauten lässt.Nun könnte ich für jeden von
Dataabgeleiteten Typ eine solche Zeilevirtual bool verify(class specialData* d) {}in die
VerifierKlasse einbauen, aber es gibt eine ganze Reihe solcher abgeleiteten Typen, und das macht irgendwie die schöne "Allgemeingültigkeit" des Codes kaput.Hat jemand Vorschläge, was ich alternativ tun könnte?
Lars
-
Schau dir vielleicht mal den Visitor bzw. Double Dispatch Pattern an...
-
verify(Data*) und verify(specialData*) sind zwei vollkommen unabhängige Funktionen. Insbesondere hat verify(specialData*) in specialVerifier nichts mit verify(Data*) in Verifier zu tun. Deshalb wird sie gar nicht berücksichtigt. Darüber hinaus werden Funktionsüberladungen immer schon zur Compilezeit durch die statischen Typen der Objekte aufgelöst.
Die Lösung ist aber einfach: teste in deinen specialVerifier::verify(data*), ob der Parameter nicht eigentlich ein specialData* ist und rufe in dem Fall die überladene Version manuell auf.
-
ipsec schrieb:
Die Lösung ist aber einfach: teste in deinen specialVerifier::verify(data*), ob der Parameter nicht eigentlich ein specialData* ist und rufe in dem Fall die überladene Version manuell auf.
Brilliant!
(Das lässt sich auf mein echtes Programm übertragen.) Ein Hoch auf das Forum! 