2016-02-15 27 views
7

Vorrei disattivare il costruttore di spostamenti nella classe. Invece di spostarmi, vorrei basarmi sul costruttore di copie. Quando provo a scrivere questo codice:Disabilitazione del costruttore di spostamenti

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
    Boo(Boo&& boo) = delete; 
}; 

Boo TakeBoo() 
{ 
    Boo b; 
    return b; 
} 

durante la compilazione Ho ricevuto errore:

error C2280: 'Boo::Boo(Boo &&)': attempting to reference a deleted function

Come posso disattivare le copie mossa costruttore e di forza, invece?

+6

semplicemente non sovraccaricare il costruttore movimento e il compilatore non genera un costruttore mossa per lui dato che c'è già un costruttore di copia –

+2

dalla norma: "Se la definizione di una classe X non esplicitamente dichiarare un costruttore di movimento, uno sarà implicitamente dichiarato come predefinito se e solo se X non ha un costruttore di copia dichiarato dall'utente [...] Quando il costruttore di movimento non è dichiarato implicitamente o fornito in modo esplicito, espressioni che altrimenti avrebbero invocato il movimento il costruttore potrebbe invece invocare un costruttore di copia. " – Pixelchemist

+1

Cosa speri di ottenere da questo? Non sembra essere significativo in alcun modo. –

risposta

17

Non creare alcuna mossa costruttore:

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
}; 

Il costruttore mossa non viene generato automaticamente fino a quando un costruttore di copia definito dall'utente è presente in modo il costruttore di copia viene chiamato.

+6

Il costruttore di spostamenti non viene generato automaticamente * se è presente un costruttore di copia *. Questo è il caso dell'esempio dell'OP, ma vale la pena sottolineare, per timore che un lettore concluda che non è necessario implementare un costruttore di mosse per evitare mosse. Ad esempio, una classe con due membri 'std :: vector' e nessun costruttore di copia o spostamento implicitamente definito otterrà un costruttore di movimento generato automaticamente che sposta i vettori. – user4815162342

4

Contrassegnare una funzione come =delete rende la funzione disponibile per la risoluzione di sovraccarico, ma se selezionata, la compilazione non riesce; questa funzionalità non è limitata ai costruttori e ad altre funzioni speciali (see here). In precedenza (circa C++ 03) il membro privato otteneva un risultato simile.

Quindi, il codice come nel campione, in pratica significa che si proibisce la costruzione di un oggetto della classe da un valore temporaneo o in scadenza (rvalue) - il costruttore di movimento.

Per correggere ciò, rimuovere completamente il costruttore di spostamento. Nel caso della classe, una volta che è presente un costruttore di copia (definito dall'utente), la traslazione non viene comunque generata in modo implicito (costruttore di movimento e operatore di assegnazione di spostamento).

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
    //Boo(Boo&& boo) = delete; 
}; 
+2

Ulteriori informazioni: contrassegnare il costruttore di movimento come cancellato dall'utente lo rende effettivamente disponibile per la risoluzione di sovraccarico; tuttavia se il costruttore di movimento è implicitamente definito come cancellato (ad esempio ciò accade se una variabile membro ha il suo costruttore di spostamenti definito come cancellato, in modo implicito o esplicito), allora * non * è disponibile per la risoluzione di sovraccarico !. (la risoluzione del sovraccarico è divertente ...) –