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?

¿Fue útil?

Solución

  

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?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top