2012-01-10 16 views
5

Duplicar posibles:
Why copy constructor is not called in this case?constructor de copia no se invoca

Considere el programa de ejemplo siguiente:

#include <iostream> 

using namespace std; 

class sample 
{ 
    private: 
     int x; 

    public: 
     sample(int a=0) : x(a) 
     { 
      cout << "default ctor invoked\n"; 
     } 

     sample(const sample& obj) 
     { 
      cout << "copy ctor invoked\n"; 
     } 

}; 

int main() 
{ 
    sample s2 = sample(20); //Line1 
    sample s3 = 20; //Line2 

    return 0; 
} 

En Line1, primero el constructor de sample clase se invoca explicitly con el argumento 20. Entonces esperaba el constructor de copia que se invocará para inicializar s2.

En Line2, primero se invoca al constructor de la clase sampleimplicitly primero con el argumento 20. Aquí también esperé que se invocara el constructor de copia para inicializar s2.

En ambos casos, el constructor de copia no se invoca? ¿Por qué está pasando esto? Creo que hay algo de malo en mi comprensión de la invocación del constructor de copias. ¿Podría alguien corregirme donde estoy yendo mal?

+0

Esto es esperado, permítame intentarlo y encontrar un buen ejemplo –

+0

Las llamadas al constructor de copia pueden omitirse en algunas situaciones. –

+0

@ R.MartinhoFernandes: Ya algunas situaciones. Pero s2 y s3 ​​deben inicializarse de alguna manera. ¿Cómo se hace sin llamar al copiador? –

Respuesta

8

Esto es esperado. Se llama copy elision.

Su expectativa es correcta, pero hicieron una excepción en C++ (para el rendimiento) que permite al compilador tratar su expresión como la inicialización directa de una instancia sin pasar por el constructor de copia.

+0

Para la primera instancia sí, el compilador puede decidir hacer una elisión de copia o no hacerlo Pero creo que en la segunda línea, 'sample s3 = 20;', entonces el compilador * debe * simplemente llamar al constructor 'int'. Creo que estoy preguntando "¿es copia elisión * opcional?" En ambos casos? " –

+1

Ninguno de los dos funcionará si el constructor de copia es inaccesible (es decir, 'privado') o eliminado. Por lo tanto, no * exactamente * se trata como inicialización directa. –

+0

ambos requieren inicialización de copia. ambos son equivalentes a 'muestra s (muestra (20));'. puede probar esto compilando después de hacer que el copiador sea privado. la elisión de copia nunca se requiere. está * permitido * por el estándar para las optimizaciones del compilador. si se elimina o no, depende de tu (s) compilador (es). – justin

0

en la primera línea no invoca al constructor de copia porque no copia un objeto. Estás asignando un objeto a otro. C++ proporciona predeterminado = operador que realiza una copia superficial. Y esto se invoca implícitamente. El constructor se llama para el objeto de la mano derecha y el constructor predeterminado se invoca para el objeto de la mano izquierda. Después de eso se invoca el operador predeterminado =.

Para la línea 2, usa el constructor que toma los parámetros int que defina. En realidad, es convertidor constructor porque toma un número entero y crea un objeto de su clase. Es por eso que C++ usa esto como un constructor de convertidor y cuando intentas asignar un entero a tu objeto, C++ invoca implícitamente este constructor de convertidor.

Espero que esto lo ayude a comprender.

+0

Cemal: Tu explicación en la Línea 1 no es correcta, creo. Como he entendido por los otros que han dado respuestas y comentarios, tanto Line1 como Line2 son inicialización de copia, pero el compilador lo optimiza para la inicialización directa al evitar llamar al constructor de copia. –

+1

Sí, tienes razón. En general, utiliza el constructor de copia cuando usa = operador pero no me di cuenta de acuerdo con el texto que me pidió el asker. Como dijiste, no pensé en la optimización del compilador y pensé directamente. Gracias por tu advertencia –

Cuestiones relacionadas