2016-06-06 32 views
8

Ho la seguente funzione membro:Quando è il costruttore di copia per il valore di ritorno avviene

Person ClassB::DoSomethingAndReturnPerson() 
{ 
RAIIMutex myLock(&m_mutex); 
return m_person; 
} 

RAIIMutex è una classe helper che riceve un mutex e lo blocca nel costruttore e rilascia nel distruttore.

m_person è di tipo Person (qualcosa di dimensioni molto piccole). Altre funzioni in altri thread potrebbero cambiare questo membro.

voglio tornare m_person per valore (restituire una copia) e, naturalmente, voglio evitare la situazione in cui l'm_person essere cambiato in un altro thread mentre viene copiato nel ritorno così ho aggiunto la serratura.

Ma cosa succede prima? Il compilatore crea prima una copia di m_person o prima chiama il distruttore di myLock?

Teoricamente facilmente risolvibile facendo qualcosa di simile a questo:

Person ClassB::DoSomethingAndReturnPerson() 
{ 
RAIIMutex myLock(&m_mutex); 
Person tmp = m_person; 
return tmp; 
} 

Ma io sono interessato a conoscere la risposta alla mia domanda.

Grazie

+0

[OT] È possibile sostituire 'RAIIMutex' con [' std :: lock_gurad'] (http://en.cppreference.com/w/cpp/thread/lock_guard) – NathanOliver

+1

il costruttore di copia non può essere chiamato a tutti, a causa di [copia elision] (https://en.wikipedia.org/wiki/Copy_elision). –

+1

@JoachimPileborg È dubbio che "m_person' sembra essere una variabile membro della classe. – NathanOliver

risposta

10

la copia-inizializzazione del il valore restituito verrà elaborato prima.

Dalla standard $6.6.3/3 The return statement [stmt.return] (sottolineatura mia)

La copia-inizializzazione dell'entità restituito viene sequenziato prima della distruzione di provvisori alla fine del pieno-espressione stabilito dalla operando della dichiarazione di reso, che a sua volta è sequenziata prima della distruzione delle variabili locali (6.6) del blocco che racchiude l'estratto conto.

+0

Grazie, dove posso trovare lo standard? È disponibile gratuitamente? – OopsUser

+0

@OopsUser Si potrebbe voler vedere [Dove trovo gli attuali documenti standard C o C++?] (Http://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or -c-standard-documents), o [The Definitive C++ Book Guide and List] (http://stackoverflow.com/a/388282/3309790), in pratica, la [bozza finale prima della standardizzazione] (http: // www. open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf) è più che adeguato (e gratuito). – songyuanyao

-1

distruttori di oggetti locali sono chiamati dopo 'l'ultima riga del codice'. Ecco una citazione pertinente standard (3.7.3/3):

Se una variabile con durata di memorizzazione automatica ha inizializzazione o un destructor con effetti collaterali, non viene distrutto prima della fine della sua bloccare, né può essere eliminato come ottimizzazione anche se sembra essere inviata, tranne che un oggetto classe o sua copia/spostamento possono essere eliminati come specificato 12,8

+0

Quindi succederà prima o dopo il costruttore di copie? Il costruttore di copie non fa parte del mio codice, il compilatore lo gestisce – OopsUser

+0

OopsUser, la risposta di @songyuanyao fornisce anche il preventivo migliore. Dopo il costruttore di copie, se è chiamato a tutti. – SergeyA