2011-06-10 28 views
8

en cuenta lo siguiente:¿Se requiere la copia CTOR aunque nunca se haya llamado?

class X { 
public: 
    X(int i) { cout << "X(int i)" << endl; } 
    X(const X& x) { cout << "X(const X& x)" << endl; } 
}; 

void main() { 
    X x1(1); 
    X x2 = X(1); 
    X x3 = (X)1; 
} 

ejecutar este código produce esta salida:

X(int i) 
X(int i) 
X(int i) 

pensé que todas las tres declaraciones anteriores son equivalentes como el CTOR copia nunca es llamado. Sin embargo, el cambio de X 's copia CTOR ser privada:

class X { 
public: 
    X(int i) { cout << "X(int i)" << endl; } 
private: 
    X(const X& x) { cout << "X(const X& x)" << endl; } 
}; 

fallará para compilar (En Visual Studio 2010) con este error:

cannot access private member declared in class 'X' 

por lo que parece el CTOR copia está implicado de alguna manera, aunque No entiendo muy bien cómo.

Gracias

Respuesta

5
X x1(1); 
X x2 = X(1); 
X x3 = (X)1; 

La razón es que todos estos no son exactamente equivalentes.

El primero es directo inicialización, mientras que el segundo y el tercero es copia-inicialización. Para la inicialización de copia, copy-constructor debe ser público o el compilador dará error.

Ahora la pregunta es, si requiere 2 y 3 de la copia-ctor a ser público, entonces ¿por qué el siguiente resultado:

X(int i) 
X(int i) 
X(int i) 

Esto sin duda dice que copia-ctor Nunca se llama lo cual es cierto. El compilador simplemente eliminó la llamada a copy-ctor. De acuerdo con § 8.5/14, en tales casos, el compilador puede eliminar la necesidad de llamar a copy-constructor. Es por eso que no ves que se llame a copy-ctor.

Un poco adentro: en el segundo y tercer caso, primero se crea un temporal llamando al X(int i), luego se suponía que este temporal se pasaba al copiador para copiar-inicializar el objeto que se estaba declarando. Pero el compilador optimiza este paso, evitando la llamada a copy-ctor.

+0

gracias de nuevo ... Tengo uno más por venir :) – dankilman

+0

Sería interesante si añadiera alguna información sobre cuáles son las diferencias reales de la segunda y tercera línea, y bajo qué circunstancias (* Según 8.5/14 en tales casos ... *) a la respuesta –

3

El X x2 = ... invoca el constructor de copia (incluso si el compilador lo optimiza más adelante). Por lo tanto, debe ser accesible.

0
  1. Este:

    X x3 = (X) 1; es fundido c-estilo de int en el objeto de tipo X

  2. Esta copia:

    X x2 = X (1);

está optimizado pero el compilador aún necesita el acceso al constructor de copias.

0

Ist objeto hace uso de constructor parrametrizado como usted lo conoce y todos los demás están utilizando copia constructor. es decir, por qué cuando se está haciendo se produce una violación de acceso privado. Los otros dos objetos están haciendo uso del constructor de copia.

Estas son las formas de usar el constructor de copias.

Cuestiones relacionadas