2011-12-08 22 views
16

En C++, ¿está garantizado que se creará un valor de retorno antes de que se destruyan las variables automáticas de la función? Aviso Cesta :: get:Valor de retorno de C++ creado antes o después de la destrucción automática de var.

class Basket 
{ 
public: 
    // Gift is a struct containing safely copyable things like int or string 
    Gift gift; 
    // Used to protect access and changes to gift 
    Mutex mutex; 

    // Copy gift into present, while locked to be thread safe 
    void put (const Gift & gift) 
    { 
    Lock lock(mutex); // Constructor locks, destructor unlocks mutex 
    this->gift = gift; // Gift assignment operator 
    } 

    // Return a memberwise-copy of gift, tries to be thread safe (but is it?) 
    Gift get() 
    { 
    Lock lock(mutex); // Constructor locks, destructor unlocks mutex 
    return gift;  // Gift copy constructor 
    } 
}; 

necesito Cesta :: llegar a realizar su copia regalo constructor (temperatura del objeto devuelto) antes de la destrucción del objeto de bloqueo. De lo contrario, el objeto regalo que se devuelve puede corromperse mediante una llamada simultánea para poner.

Mis pruebas muestran que la copia del regalo se creó antes de la destrucción del bloqueo, sin embargo, ¿está garantizado? Si no, tendré que crear un segundo temporal dentro de la función, como por ejemplo:

Gift get() 
    { 
    Gift result; 
    { 
     Lock lock(mutex); 
     result = gift; 
    } 
    return result; 
    } 

Respuesta

12

Sí, la variable automático permanecerá en su alcance, hasta después de la vuelta está terminado. Esto es especialmente cierto si usted está utilizando un compilador que optimiza el return, por ejemplo:

Gift get() 
{ 
    Lock lock(mutex); 
    return gift; 
} 

Gift g = basket.get(); 

Cuáles serían los equivilent a esta secuencia:

Gift g; 
Lock lock(mutex); 
g = Gift(gift); 
~lock(); 

se puede optimizar para actuar de la misma familia:

void get(Gift &ret) 
{ 
    Lock lock(mutex); 
    ret = gift; 
} 

Gift g; 
basket.get(g); 

Cuáles serían los equivilent a esta secuencia:

Gift g; 
Lock lock(mutex); 
g = gift; 
~lock(); 

En otras palabras, un temporal se puede eliminar durante el return.

3

Está garantizado. El valor de retorno se copia (si es necesario) antes de que se produzca la destrucción. Aquí hay una pregunta/respuesta similar que da una buena descripción de la secuencia.

Scope and return values in C++

+1

No existen registros en el estándar C++. (Bueno, existe la palabra clave 'register', pero eso perdió su significado hace mucho tiempo). Además, la mayoría de los objetos no cabrían en un solo registro, de todos modos. – fredoverflow

+0

Si se devolvía un objeto local, entonces, seguro, tendría que copiarse antes de que se destruyera. Sin embargo, esto es otra cosa. Tengo un miembro de datos de la clase que se devuelve, por lo que la semántica de exactamente cuándo se produce la copia parece diferente. – maxpolk

+0

@maxpolk Está devolviendo el miembro por valor. Habrá una copia a menos que el compilador pueda optimizarla para una asignación de referencia como mostró Remy. Si devolviera una referencia o un puntero, la cerradura aún se destruiría después. – AJG85

Cuestiones relacionadas