Verwendung = Standard in der Bedeutung von = delete

8

Der folgende Code ist gut kompiliert:

%Vor%

Bis ich eine Instanz der Klasse D erstellen muss:

%Vor%

Gibt es einen Grund (Anwendungsfall), = default für den Konstruktor von D zuzulassen, wenn es tatsächlich als = delete; funktioniert?

    
alexolut 27.12.2017, 11:20
quelle

3 Antworten

11

g++ gibt eine schöne Erklärung in dem Fehler:

  

bla.cpp: 6: 5: Hinweis: 'D :: D ()' wird implizit gelöscht, weil die Standarddefinition nicht korrekt ist:        D () = Standard;

Der Standardkonstruktor versucht, alle Teile von D zu konstruieren. Sie haben keine Felder, aber es hat ein initiales B - welches keinen leeren Konstruktor hat, nur ein int eins.

Das Standardverhalten ist sinnvoll - D sollte keinen leeren Konstruktor haben, es sei denn es gibt explizit an, mit welcher int die B erstellt werden soll, und der Compiler möchte nicht raten. Andernfalls haben Sie ein D -Objekt, und abhängig davon, was im B -Konstruktor passiert, kann B Junk enthalten, zum Beispiel wenn Sie ein Feld initialisieren.

Ich bin mir nicht sicher, ob du deine Frage wörtlich gemeint hast, wenn du fragst, warum das " erlaubt " ist, da der B Standardkonstruktor gelöscht wird, aber ich kann mir zwei Gründe vorstellen:

  1. Dieses Verhalten ist gut definiert, und es gibt keinen Grund, es abzulehnen. Das Erkennen des Fehlers nur, wenn Sie versuchen, etwas illegal zu konstruieren, ist sowieso getan.
  2. Es ist flexibler - wenn B so geändert wird, dass ein Standardkonstruktor automatisch D hat, wird ein solcher verwendet.
kabanus 27.12.2017, 11:30
quelle
6
  

Gibt es einen Grund (Use Case) zu erlauben = Standard für Ds Konstruktor, wenn es eigentlich funktioniert als = delete;?

Es funktioniert nicht als =delete . Es sagt nur, was es sagen soll. Dass Sie explizit möchten, dass der Compiler eine Standardimplementierung generiert.

Es ist einfach so, dass der Compiler, der erzeugt wurde, gelöscht werden muss. Weil der Standardkonstruktor von B implizit gelöscht wird.

    
StoryTeller 27.12.2017 11:30
quelle
1

B hat einen nicht standardmäßigen Konstruktor (sein Konstruktor verwendet ein Argument, das keinen Standardwert hat).

Die abgeleitete Klasse D hat daher keinen Standardkonstruktor, ihr Standardkonstruktor wird gelöscht (da der Compiler keinen Konstruktor für D erzeugen kann, der den B(int) -Konstruktor seiner Elternklasse aufrufen kann.)

D() = default; sagt nur, dass Sie den Standardkonstruktor für D wollen, und wie oben beschrieben, wird der Standardkonstruktor gelöscht.

    
nos 27.12.2017 11:34
quelle

Tags und Links