Kovarianz und Kontravarianz
-
Hallo zusammen
Ich beschäftige mich gerade mit der Typentheorie : http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) und habe hierzu eine Frage:Ich verstehe zwar was Kontravarianz bedeutet, aber ich habe Mühe dies in den Kontext der folgenden Aussage zu bringen:
The problem for instances of B is how to be perfectly substitutable for instances of A.
B is abgeleitet von A. Also ich kann mir beim besten Willen nich vorstellen, wie Instancen vom Typ A und B austaschbar sein können, wenn eine Methode vom Typ B einen generelleren Typ akzeptiert als A
Bspw:
class P1{ }; class P2:P1{ }; class C1{ public virtual void DoSomething(P2 p2); }; class C2{ public void DoSomething(P1 p1); }; C1 *c1 = new C1(); C2 *c2 = new C2(); P1 *p1 = new P1(); c1->DoSomething(p1); c2->DoSomething(p1);
Das gibt doch einen Kompilerfehler??? Aber genau dies ist doch "Kontravarianz"?
Oder bringe ich da etwas durcheinander?Mfg Samuel
-
Ishildur schrieb:
The problem for instances of B is how to be perfectly substitutable for instances of A.
B is abgeleitet von A. Also ich kann mir beim besten Willen nich vorstellen, wie Instancen vom Typ A und B austaschbar sein können
Vorsicht bei der Formulierung: die Austauschbarkeit ist nur in einer Richtung gefordert (B muß A substituieren können).
Ishildur schrieb:
wenn eine Methode vom Typ B einen generelleren Typ akzeptiert als A
Wenn B.f() C und A.f() C' erwartet, dann ist der Aufruf von B.f() mit C' legitim, demnach A durch B ersetzbar.
Ishildur schrieb:
Das gibt doch einen Kompilerfehler???
Wenn du all die Kleinigkeiten beseitigst, solltest du mit einer Warnung (C2::DoSomething() verdeckt C1::DoSomething()) davonkommen, aber semantisch funktioniert es trotzdem nicht, weil C++ Kontravarianz für Methodenargumente nicht direkt unterstützt. Der naheliegende Workaround wäre etwa folgendes:
struct P1 {}; struct P2 : P1 {}; struct C1 { virtual void f (P2*); }; struct C2 : C1 { virtual void f (P2* p) { f (static_cast <P1*> (p)); } virtual void f (P1*); };