C ++ constructor de copia, los temporales y la semántica de copia
Pregunta
Para este programa
#include <iostream>
using std::cout;
struct C
{
C() { cout << "Default C called!\n"; }
C(const C &rhs) { cout << "CC called!\n"; }
};
const C f()
{
cout << "Entered f()!\n";
return C();
}
int main()
{
C a = f();
C b = a;
return 0;
}
la salida que recibo es:
Entered f()!
Default C called!
CC called!
Desde f()
está regresando por valor, que debe devolver un temporal. Como T a = x;
es T a(x);
, ¿no llama al constructor copia para la construcción de a
, con el temporal pasado-en como su argumento?
Solución
Desde
f()
está regresando por valor, que debe devolver un temporal. ComoT a = x;
esT a(x);
, ¿no llama al constructor copia para la construcción dea
, con el temporal pasado-en como su argumento?
Busque la optimización del valor de retorno. Esto se activa de forma predeterminada. Si está en Windows utilizando MSVC 2005+ puede utilizar /Od
desactivar esta opción y obtener el resultado deseado (o -fno-elide-constructors
en GCC). También, para ver MSVC este artículo .
12,8 clase copiar objetos
15 Cuando se cumplen ciertos criterios, una se permite omitir la aplicación de copiar construcción de un objeto de clase, incluso si el constructor de copia y / o destructor para el objeto de tener lado efectos. En tales casos, la trata de implementación del origen y objetivo de la operación de copia omitido como simplemente dos formas diferentes de se refieren al mismo objeto, y el destrucción de ese objeto se produce en la última de las veces cuando los dos objetos tendrían sido destruido sin la optimization.115 Esta elisión de copia las operaciones se permite en el siguiente circunstancias (que puede ser combinado para eliminar múltiples copias):
- en una instrucción de retorno en una función con un tipo de retorno de clases, cuando la expresión es el nombre de una automático de objetos no volátil con el mismo cv-incondicional tipo que el función de tipo de cambio, la copia operación puede ser omitido por la construcción del objeto automática directamente en el regreso de la función valor - en un saque de banda expresión, cuando el operando es el nombre de una automático de objetos no volátil, la copiar operación desde el operando a la objeto de excepción (15.1) se puede omitir por la construcción del objeto automático directamente en el objeto de excepción
- cuando un objeto de clase temporal que tiene no se ha unido a una referencia (12.2) se copian en un objeto de clase con el mismo tipo cv-sin reservas, la copia operación puede ser omitido por la construcción del objeto temporal directamente en el objetivo de la copia omitido
- cuando el excepción, la declaración de una excepción handler (Cláusula 15) declara un objeto del mismo tipo (excepto para cv-calificación) como la excepción objeto (15.1), la copia operación puede omitirse mediante el tratamiento de la excepción, la declaración como un alias para el objeto de excepción si el significado de el programa será sin cambios, excepto para la ejecución de los constructores y destructores para el objeto declarados por la excepción-declaración.
Nota: El énfasis es mío
Otros consejos
Este es un ejemplo de optimización Valor de retorno (RVO) características que admite el compilador.
Un constructor de copia podría no ser llamado cuando regrese por valor.
Utilice la opción -fno-elide-constructors
de GCC para desactivar esa opción.
Creo que se llama retorno optimización valor .
Asumo cuando los rendimientos f()
C
objeto, el objeto se asigna en el espacio de pila del método que llama se requiere, por tanto, ninguna copia para inicializar C a
. Esta es su default C called
.
C b = a
Esto provoca un constructor de copia, por tanto, su CC called
.
Por cierto, el ejemplo de wiki parece bastante similar a su código.