2015-11-27 8 views
24

Inspiriert von der Post Why does destructor disable generation of implicit move methods?, ich frage mich, ob das gleiche gilt für die Standard virtuellen Destruktor, z.Verhindert ein virtueller Standarddestruktor Compiler-generierte Verschiebeoperationen?

class WidgetBase // Base class of all widgets 
{ 
    public: 
     virtual ~WidgetBase() = default; 
     // ... 
}; 

Da die Klasse eine Basisklasse einer Widgets Hierarchie sein Ich habe seine destructor virtuellen sollte definieren Speicherlecks und nicht definiertes Verhalten zu vermeiden, wenn mit der Basisklasse Zeigern arbeiten. Andererseits möchte ich nicht verhindern, dass der Compiler automatisch Verschiebeoperationen erzeugt.

Behindert ein virtueller Standarddestruktor compilergenerierte Verschiebeoperationen?

Antwort

21

Ja, die Deklaration eines beliebigen Destruktors verhindert die implizite Deklaration des Move-Konstruktors.

N3337 [class.copy]/9: Wenn die Definition einer Klasse X einen Umzug Konstruktor nicht explizit deklarieren, wird man implizit als ob und

  • X kein Benutzer deklarierte Copykonstruktor hat nur dann, wenn

    vorbelegt deklariert werden ,
  • X nicht über eine benutzer erklärt Kopie Zuweisungsoperator,
  • X keinen Benutzer deklarierte Bewegung Zuweisungsoperator hat,
  • X hat keinen vom Benutzer deklarierten Destruktor und
  • . Der Move-Konstruktor wäre nicht implizit als gelöscht definiert.

die destructor Deklarieren und als default zählt als benutzer erklärt definieren.

Sie müssen den Zug Konstruktor deklarieren und definieren es als default selbst:

WidgetBase(WidgetBase&&) = default; 

Beachten Sie, dass dies wiederum den Kopierkonstruktor als delete definieren, so dass Sie auch zu default, die man braucht :

WidgetBase(const WidgetBase&) = default; 

Die Regeln für kopieren und verschieben sowie Zuweisungsoperatoren sind ziemlich ähnlich, werden Sie zu default sie so haben, wenn Sie es wünschen.