2015-11-27 14 views
24

Ispirato al post Why does destructor disable generation of implicit move methods?, mi chiedevo se lo stesso vale per il distruttore virtuale predefinito, ad es.Un distruttore virtuale predefinito impedisce le operazioni di spostamento generate dal compilatore?

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

Poiché la classe è destinato ad essere una classe base di una gerarchia widget di devo definire il suo distruttore virtuale per evitare perdite di memoria e comportamento indefinito quando si lavora con puntatori alla classe base. D'altra parte non voglio impedire al compilatore di generare automaticamente operazioni di spostamento.

Un distruttore virtuale predefinito impedisce le operazioni di spostamento generate dal compilatore?

risposta

21

Sì, dichiarando che qualsiasi distruttore impedirà la dichiarazione implicita del costruttore di spostamenti.

N3337 [class.copy]/9: Se la definizione di una classe X non dichiara esplicitamente un costruttore mossa, uno sarà implicitamente dichiarato come default se e solo se

  • X non ha un costruttore di copia user-dichiarata ,
  • X non ha un operatore di assegnamento copia utente-dichiarato,
  • X non ha un operatore di assegnazione mossa dall'utente dichiarato,
  • X non ha un distruttore dichiarato dall'utente e
  • il costruttore di movimento non viene definito implicitamente come eliminato.

Dichiarare il distruttore e impostazione quale default conta come dall'utente dichiarato.

Avrete bisogno di dichiarare il costruttore di movimento e definirlo come default te:

WidgetBase(WidgetBase&&) = default; 

Si noti che questo a sua volta definisce il costruttore di copia come delete, quindi avrai bisogno di default anche quello :

WidgetBase(const WidgetBase&) = default; 

Le regole per copiare e spostare gli operatori di assegnazione sono piuttosto simili e, in modo dovrete default loro se li volete.