Daniel A. schrieb:
> Wiso will der Compiler die classe protocol im copy constructor der
> classe http1v1 instanzieren, wo dies doch der copy constructor der
> classe http tun muss, welche explizit im copy constructor der classe
> http1v1 instanziert wird?
Normalerweise werden für eine Klasse, die mehrfach in der
Vererbungshierarchie auftaucht, auch mehrere Kopien angeleget, zum
Beispiel enthält in:
1 | class A {};
|
2 | class B: public A {};
|
3 | class C: public A {};
|
4 | class D: public B, public C {};
|
die Klasse D zwei Kopien von A, einmal in B und einmal in C.
Insbesondere wird auch der Konstruktor für A zweimal aufgerufen, einmal
von B und einmal von C, jeweils für die eigene Kopie.
Die virtuelle Vererbung soll genau das verhindern. In
1 | class A {};
|
2 | class B: virtual public A {};
|
3 | class C: virtual public A {};
|
4 | class D: public B, public C {};
|
enthält D nur noch eine Kopie von A, die von B und C gemeinsam genutzt
wird. Da der Konstruktor von A aber nur einmal aufgerufen werden darf
und nicht eindeutig bestimmbar ist, ob dieses sinnvoller durch B oder C
erfolgen soll, legt der Standard fest, dass der Konstruktor von A immer
von der am weitesten abgeleiteten Klasse, in diesem Fall also von D,
aufgerufen wird. Der Konstruktor von D muss also (implizit oder
explizit) einen Aufruf des Konstruktors von A enthalten:
1 | D::D(): A(), B(), C() {}
|
Wird er nicht explizit angegeben, so wird er durch den Compiler ergänzt.
Da in Deiner Klasse http1v1 der Konstruktor für protocol fehlt wird
der Compiler den Default-Konstuktor implizit ergänzen, der aber offenbar
nicht existiert. Der Konstruktor für protocol in der Klasse http ist
in diesem Fall wirkungslos. Er wir nur gerufen, wenn es in der
Vererbungshierarchie kein weiteres Auftreten von protocol gibt, was
hier aber offenbar nicht der Fall ist (d.h. es muss in der
Vererbungshierarchie von http1v1 mindestens ein weiteres Auftreten
von protocol geben).