2016-06-06 11 views
8

Ich habe folgende Memberfunktion:Wenn der Copykonstruktor für den Rückgabewert geschieht

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

RAIIMutex ist eine Hilfsklasse, die einen Mutex recieves und sperrt sie in den Konstruktor und gibt in der destructor.

m_person ist vom Typ Person (etwas sehr klein). Andere Funktionen in anderen Threads können dieses Mitglied ändern.

Ich möchte m_person nach Wert zurückgeben (eine Kopie zurückgeben) und natürlich möchte ich vermeiden, dass die m_person in einem anderen Thread geändert wird, während es in der Rückkehr kopiert wird, so habe ich die Sperre hinzugefügt.

Aber was passiert zuerst? Erstellt der Compiler zuerst eine Kopie von m_person oder ruft zuerst den Destruktor myLock auf?

Theoretisch es easly auflösbar durch so etwas wie dies zu tun:

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

Aber ich bin daran interessiert, die Antwort auf meine Frage zu kennen.

Dank

+0

[OT] Sie können ersetzen 'RAIIMutex' mit [' std :: lock_gurad'] (http://en.cppreference.com/w/cpp/thread/lock_guard) – NathanOliver

+1

Der Copy-Konstruktor nicht aufgerufen werden kann überhaupt wegen [elision kopieren] (https://en.wikipedia.org/wiki/Copy_elision). –

+1

@JoachimPileborg Das ist zweifelhaft, da 'm_person' eine Klassenmitgliedsvariable zu sein scheint. – NathanOliver

Antwort

10

die Kopie-Initialisierung der wie angegeben beseitigt werden Der zurückgegebene Wert wird zuvor verarbeitet.

Vom Standard $6.6.3/3 The return statement [stmt.return] (Hervorhebung von mir)

Die Kopie-Initialisierung der zurückgegebenen Einheit wird vor der am Ende des Voll Ausdrucks Zerstörung von Provisorien durch die Operanden des etablierten sequenziert return-Anweisung, die wiederum ist vor der Zerstörung der lokalen Variablen (6.6) des Blocks sequenziert, die die Return-Anweisung.

+0

Danke, wo finde ich den Standard? Ist es kostenlos verfügbar? – OopsUser

+0

@OopsUser Sie können sehen, [Wo finde ich die aktuellen C oder C++ Standard-Dokumente?] (Http://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or -c-standard-documents) oder [The Definitive C++ Buch Guide and List] (http://stackoverflow.com/a/388282/3309790), im Grunde der [endgültige Entwurf vor der Normung] (http: // www. open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf) ist mehr als ausreichend (und kostenlos). – songyuanyao

-1

Destructors der lokalen Objekte werden nach den Worten ‚in der letzten Zeile des Codes‘ genannt. Hier ist ein relevantes Zitat von Standard (3.7.3/3):

Wenn eine Variable mit automatischer Speicherdauer der Initialisierung hat oder einen destructor mit Nebenwirkungen, es wird nicht vor Ende zerstört wird sein Block, noch sollen sie als Optimierung beseitigt werden, selbst wenn es ungenutzt zu sein scheint, mit der Ausnahme, dass ein Klassenobjekt oder dessen kopieren/verschieben kann in 12,8

+0

Also wird es vor oder nach dem Kopierkonstruktor passieren? Der Kopierkonstruktor ist nicht Teil meines Codes, der Compiler handhabt es – OopsUser

+0

OopsUser, die Antwort von @songyuanyao stellt sogar das bessere Zitat zur Verfügung. Nach dem Kopierkonstruktor, wenn es überhaupt aufgerufen wird. – SergeyA