9

Ich habe einen Anwendungsfall, dass mein Objekt in keiner Weise kopiert werden darf. Ich habe eine übertrieben vollständige Liste der Löschungen von Kopierkonstruktoren und Kopierzuweisungsoperatoren geschrieben. Es gibt so viele von ihnen, dass ich nicht sicherstellen kann, welche zu verwenden, und manchmal macht mich das paranoid. Ich muss sie nicht alle in meinem Code schreiben, oder? Also, um das Kopieren von Objekten zu verhindern, welche von denen sollte ich verwenden?Löschen von Kopierkonstruktoren und Kopieren von Zuweisungsoperatoren. Welche von ihnen sind essentiell?

 MyClass    (  MyClass &) = delete; 
     MyClass    (const MyClass &) = delete; 
     MyClass    (  MyClass &&) = delete; 
     MyClass    (const MyClass &&) = delete; 
     MyClass operator=(  MyClass &) = delete; 
     MyClass operator=(const MyClass &) = delete; 
const MyClass operator=(  MyClass &) = delete; 
const MyClass operator=(const MyClass &) = delete; 
     MyClass & operator=(  MyClass &) = delete; 
     MyClass & operator=(const MyClass &) = delete; 
const MyClass & operator=(  MyClass &) = delete; 
const MyClass & operator=(const MyClass &) = delete; 
     MyClass && operator=(  MyClass &) = delete; 
     MyClass && operator=(const MyClass &) = delete; 
const MyClass && operator=(  MyClass &) = delete; 
const MyClass && operator=(const MyClass &) = delete; 
     MyClass operator=(  MyClass &&) = delete; 
     MyClass operator=(const MyClass &&) = delete; 
const MyClass operator=(  MyClass &&) = delete; 
const MyClass operator=(const MyClass &&) = delete; 
     MyClass & operator=(  MyClass &&) = delete; 
     MyClass & operator=(const MyClass &&) = delete; 
const MyClass & operator=(  MyClass &&) = delete; 
const MyClass & operator=(const MyClass &&) = delete; 
     MyClass && operator=(  MyClass &&) = delete; 
     MyClass && operator=(const MyClass &&) = delete; 
const MyClass && operator=(  MyClass &&) = delete; 
const MyClass && operator=(const MyClass &&) = delete; 
+0

Das sieht in der Tat ein wenig paranoid :) – melak47

+4

Es wird auch nicht kompilieren, weil Sie nicht auf Rückgabewert überladen können. – interjay

+3

Außerdem hast du 'volatile' vergessen ;-) –

Antwort

15

Sie müssen nur einen einzelnen Kopierkonstruktor markieren und den Zuweisungsoperator als delete kopieren. Das Vorhandensein der Kopierversionen verhindert die implizite Deklaration des Verschiebungskonstruktors und Verschiebezuweisungsoperators, und die Deklaration eines Formulars einer speziellen Kopffeldfunktion unterdrückt die implizite Deklaration anderer Formulare.

MyClass (const MyClass&) = delete; 
MyClass& operator= (const MyClass&) = delete; 

anzumerken, dass nach der C++ 11, implizit-Definition des Zuweisungsoperators als ausgefallen ist veraltet, und es sollte stattdessen als gelöscht festgelegt werden.

+1

Nur ein sehr kleiner Nitpick, und ich könnte falsch liegen. Ist die * Definition * nicht veraltet, nicht die * Deklaration *? Sie werden immer deklariert, aber ihre Definition wird gelöscht. Aber ich bin kein sehr guter Sprachanwalt. – luk32

+0

@ luk32 ah, du hast Recht, es sollte stattdessen implizit deklariert und als gelöscht definiert werden ('[class.copy]/18'), danke. – TartanLlama

3

copy constructor

MyClass    (const MyClass &) = delete; 

assignement operator

MyClass & operator=(const MyClass &) = delete; 

Dies sind die einzigen Kopierkonstruktoren ans assignement Operatoren implizit definiert kopieren.

+2

' operator = 'ist kein Konstruktor; und im Allgemeinen können andere Konstruktoren implizit definiert sein - aber das Vorhandensein von benutzerdefiniertem 'MyClass (const MyClass &)' unterdrückt die anderen Konstruktoren. –

+3

Ihre "Lösung" ist gut, aber die Antwort ist eigentlich falsch. Die richtige Argumentation ist, dass alle Zuweisungsoperatoren und -konstruktoren implizit definiert sind, es sei denn, Sie definieren unter anderem eine von Hand. Die Löschung gilt als Definition für diesen Zweck. – luk32