Forum: PC-Programmierung C++ Problem bei Expliziter Initialisierung im Copy Constructor


von Daniel A. (daniel-a)


Angehängte Dateien:

Lesenswert?

Hallo

Ich bekomme eine Fehlermeldungen beim kompilieren und verstehe nicht, 
wie dieser zustandekommen konnte, und wie ich ihn beheben kann.
1
WebsocketServer/server/protocol/http/versions/http_v1.1.cpp: In constructor ‘protocol::http1v1::http1v1(const protocol::http&)’:
2
WebsocketServer/server/protocol/http/versions/http_v1.1.cpp:10:43: error: no matching function for call to ‘protocol::protocol::protocol()’

Die Fehlermeldung bezieht sich auf diese Zeile:
1
  http1v1::http1v1(const http& h) : http(h) {

Die Classe http ist folgendermasen definiert:
1
  class http : public virtual protocol {
2
...
3
    public:
4
      http(const http&);
5
      http(connection::connection*const x);
6
...

Die classe protocol wird im copy constructor der classe http 
instanziert:
1
  http::http(const http& x) : protocol((const protocol&)x) {  }

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?

Mit Freundlichen grüssen
Daniel Abrecht

von Dr. Sommer (Gast)


Lesenswert?

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?

Vermutlich weil http1v1 virtuell von http ableitet ("class http1v1 : 
virtual public http"). Brauchst du das wirklich?!

von A. H. (ah8)


Lesenswert?

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).

: Bearbeitet durch User
von Daniel A. (daniel-a)


Lesenswert?

Danke für die Hilfe!

Jetzt funktioniert es und ich verstehe auch warum.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.