2015-10-13 9 views
9

Vor 11 C++, ich diese verwenden könnte eine Klasse nicht kopierbar zu machen:Machen Sie eine Klasse nicht-kopierbaren * und * unbewegliche

private: 
MyClass(const MyClass&); 
MyClass& operator=(const MyClass&); 

Mit C++ 11, kann ich es tun dies wie statt:

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

Wenn die Klasse mit der gelöschten Kopie und Zuordnung verwendet, gibt es eine Chance, dass ein Standard-Bewegung Operator erzeugt wird? Und die Klasse wird nicht genau kopiert, sondern bewegt (was ist irgendwie ähnlich)?

Also, ich habe dies zu tun Standard bewegen Bau und assignmnent zu verhindern:

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

...?

+0

Sie brauchen es nicht. Persönlich habe ich sowas in eine private Basisklasse namens 'NoCopyOrMove' gesteckt, damit es meinen Code nicht durcheinander bringt. – MikeMB

+0

'MyClass (MyClass &&) = delete;' wird die anderen implizit deaktivieren – sp2danny

Antwort

14

Wie bereits in den Kommentaren erwähnt, wurden in C++ 11 gelöschte Konstruktoren eingeführt. Zur Beantwortung Ihrer Frage, die folgenden Regeln halten im Allgemeinen:

  1. Die beiden Kopiervorgänge unabhängig sind. Das Deklarieren des Kopierkonstruktors verhindert nicht, dass der Compiler eine Kopierzuweisung generiert und umgekehrt. (Wie in C++ 98)
  2. Verschiebeoperationen sind nicht unabhängig. Declare verhindert entweder, dass der Compiler den anderen generiert. (Im Unterschied zu Kopiervorgängen.)
  3. Wenn eine der Kopieroperationen deklariert ist, wird keiner der Verschiebevorgänge generiert.(Ihr Fall.)
  4. Wenn einer der Verschiebevorgänge deklariert ist, wird keiner der Kopiervorgänge generiert. Dies ist die entgegengesetzte Regel des vorherigen.
  5. Wenn ein Destruktor deklariert ist, wird keiner der Verschiebevorgänge generiert. Kopiervorgänge werden weiterhin für die umgekehrte Kompatibilität mit C++ 98 generiert.
  6. Standardkonstruktor wird nur generiert, wenn kein Konstruktor deklariert ist. (Das gleiche wie in C++ 98)

Wie in den Kommentaren aufgefordert, hier sind einige Quellen (C++ 11 Entwurf ist N3242):

  • Kopiervorgänge: § 12.8.8, § 12.8.19
  • verschieben Operationen: § 12.8.10, § 12.8.21
  • Standardkonstruktors: § 12.1.5
+1

woher hast du diese Fakten? – Yola

+3

Es war mein Wissen :) Für Ihre Anfrage habe ich meine Antwort erweitert und einige Zitate zum C++ - Standard hinzugefügt, um es zu unterstützen. – mcserep

10

Verschiebungskonstruktor/Zuordnung wird nicht generiert, wenn Sie einen Kopierkonstruktor deklarieren. also

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

ist nicht erforderlich.

Sie können es noch hinzufügen, um expliziter zu sein.

+0

Explizit zu sein ist gut: Ich deklariere immer alle Operatoren und lösche selektiv diejenigen, die ich nicht brauche.Es macht meine Absicht klar und nur für den Fall, dass es einen Compiler-Fehler gibt, sollte es immer noch so funktionieren, wie ich es erwarte. –