2014-07-05 10 views
8

Si consideri il seguente frammento di codice:Perché viene invocato il distruttore di un oggetto spostato dall'oggetto?

struct foo { 
    std::string id; 
}; 

int main() { 
    std::vector<foo> v; 

    { 
    foo tmp; 
    v.push_back(std::move(tmp)); 
    } 
} 

LIVE DEMO

Nel pezzo di codice dimostrato:

  1. Il costruttore di default della classe foo sta per essere richiamato per la costruzione di oggetti tmp.
  2. Il costruttore di movimento della classe foo sta per essere richiamato nella dichiarazione v.push_back(std::move(tmp));.
  3. Il distruttore di class foo verrà invocato due volte.

Domande:

  1. Perché il distruttore di un oggetto spostato dalla viene chiamato due volte?
  2. Cosa viene spostato dall'oggetto che viene effettivamente spostato?
+2

L'oggetto spostato da è solo destrutturato una volta. Ogni oggetto viene creato una volta e distrutto una volta. Le due chiamate del distruttore sono per 'tmp' e l'oggetto nel vettore. –

risposta

2

Perché il distruttore di un oggetto spostato viene chiamato due volte?

Il primo distruttore distrugge il mosso da-tmp quando passa nell'ambito al primo } in main(). Il secondo distruttore distrugge lo spostamento foo creato dall'utentein v alla fine di main() quando v esce dallo scope.

Che cosa viene spostato dall'oggetto che viene spostato realmente?

I mossa costruttore spostare-costrutti generati dal compilatore id, che è un std::string. Un costruttore di movimento di std::string di solito assume la proprietà del blocco di memoria nell'oggetto spostato da un oggetto che memorizza la stringa effettiva e imposta l'oggetto spostato da uno stato valido ma non specificato (in pratica, probabilmente una stringa vuota).

+0

"distrugge tmp, dopo che è stato spostato da": Beh, viene distrutto in virtù dell'uscita dall'ambito (il '}' dopo il push_back), non immediatamente dopo che è stato spostato da (il ';' dopo il push_back). Questo è importante se c'è più codice tra 'push_back' e'} '. –

+0

@AndreKostur Non intendevo implicare che ci sia una connessione casuale tra il 'tmp' da cui viene spostato e il' tmp' che viene distrutto; intendeva spiegare perché il primo output del distruttore nella demo dell'OP ha stampato una stringa vuota e descrivere lo stato di 'tmp' al momento della sua distruzione. Vedo che può essere fonte di confusione, tuttavia, così chiarito. –

Problemi correlati