Durch das Löschen des Kopierkonstruktors werden geerbte Konstruktoren getrennt

9

Ich versuche, die Konstruktorvererbung von C ++ 11 zu verwenden. Das folgende Snippet (von irgendwoher kopiert, woher ich mich nicht erinnere) funktioniert ganz gut:

%Vor%

Das heißt, bis die durch den Kommentar markierte Zeile hinzugefügt wird; denn dann bricht die Hölle los:

%Vor%

Es sieht so aus, als ob das Löschen des Kopierkonstruktors irgendwie den Standardkonstruktor von Base unzugänglich gemacht hätte. Das Problem zu googeln hat nichts Nützliches gebracht; SO vorgeschlagen dieses Problem , aber soweit ich Versteh, ich benutze in diesem Snippet keine Kopierinitialisierung. Könnte jemand etwas Licht auf das werfen, was hier passiert ist?

(Der Compiler, der die obige Nachricht generiert hat, ist GCC 4.8.2; clam gibt jedoch eine ähnliche Fehlermeldung zurück.)

    
David Nemeskey 05.10.2015, 17:46
quelle

3 Antworten

10

Das Problem ist, dass das Markieren eines Kopierkonstruktors mit delete es benutzerdefiniert macht, wodurch der Standardkonstruktor dieser Klasse gelöscht wird (in Ihrem Fall Derived ). Das Verhalten kann in diesem einfachen Code gesehen werden:

%Vor%

Als Nebenbemerkung: Selbst wenn Base::Base() vererbt würde, würde der Compiler es so sehen %Code%. Aber Derived(): Base(){} wird gelöscht, daher kann Derived nicht wirklich aufgerufen werden. Im Allgemeinen ist eine Base::Base() -Anweisung nur syntaktischer Zucker für den entsprechenden vom Compiler generierten using Base::Base .

    
vsoftco 05.10.2015, 17:52
quelle
4

Wenn Sie einen benutzerdefinierten Konstruktor definieren, müssen Sie explizit einen Standardkonstruktor angeben. Ie.

%Vor%     
SergeyA 05.10.2015 17:54
quelle
4

Vererben von Konstruktoren erhält nicht die speziellen Konstruktoren - leer, kopieren, verschieben. Dies ist, weil das, was Sie buchstäblich fragen, fast immer eine schlechte Idee ist.

Untersuchen:

%Vor%

Möchten Sie wirklich möchten, dass derived(base const&) existiert? Oder base(base&&) ? Beide würden hoffnungslos derived schneiden.

Die Gefahr, dass diese Operationen "versehentlich" passieren, bedeutet, dass Sie sie explizit mitbringen müssen, wenn Sie sie wollen.

Die copy / move / default-Ctors rufen standardmäßig nur die übergeordnete Version und die ctors der Membervariablen auf. Es besteht normalerweise keine Notwendigkeit, sie von Ihren Eltern zu übernehmen.

Sobald Sie jedoch =delete , =default oder einen dieser speziellen Ctors definiert haben, werden die anderen nicht mehr vom Compiler generiert. Also müssen Sie =default die anderen, wenn Sie immer noch wollen, dass sie bleiben.

    
Yakk 05.10.2015 18:06
quelle