2012-01-08 20 views
6

Estoy aprendiendo ctors ahora y tengo algunas preguntas. En estas líneas:C++ creación de objetos y constructor

Foo obj(args); 

Foo obj2; 
obj = Foo(args); 

Foo obj3 = Foo(args); 

Primera parte: sólo el 1 constructor llamado (Foo) y obj se inicializa. Entonces, 1 creación de objeto.

Segunda parte: creación del objeto temporal obj2, llamando al ctor predeterminado para ello. Las siguientes líneas crearemos otra copia de Foo y la pasaremos a operator=(). ¿Está bien? Entonces, 3 objetos temporales locales, 2 llamadas de constructor.

Tercera parte: crea 1 objeto Foo y pásalo a operator=(). Entonces, 2 objetos temporales y 1 llamada de ctor.

¿Entiendo esto bien? Y si es cierto, ¿el compilador (por ejemplo, último gcc) optimizará estos en casos comunes?

+0

'operator =()' normalmente recibe su argumento por referencia, por lo que no hay copias al llamarlo. – rodrigo

+0

obj3 se crea realmente utilizando el constructor de copia no el operador de asignación. –

Respuesta

6

voy a comentar sobre el tercero primera:

Foo obj3=Foo(args); 

No utiliza operator= que se llama copia-asignación. En cambio, invoca copy-constructor (teóricamente). No hay asignación aquí. Entonces, teóricamente, hay dos objetos creados, uno es temporal y el otro es obj3. El compilador podría optimizar el código, evitando por completo la creación temporal de objetos.

Ahora, la segunda:

Foo obj2;   //one object creation 
obj = Foo(args); //a temporary object creation on the RHS 

Aquí la primera línea crea un objeto, llamando al constructor por defecto. Luego llama al operator= pasando el objeto temporal creado a partir de la expresión Foo(args). Entonces, hay dos objetos que solo el operator= toma el argumento por referencia const (que es lo que debería hacer).

Y en cuanto al primero, tienes razón.

+0

Bien, gracias. Pero de todos modos, en el primer caso solo se crean 1 objetos de tipo 'Foo', en el tercero: 2 objetos? – Ockonal

+0

No, de acuerdo con las especificaciones, la parte 1 y la parte 3 son dos formas de especificar lo mismo. No hay diferencia en la implementación. –

+2

@MrLister: No. Hay una sutil diferencia entre '1' y' 3'. Simplemente escriba un código de prueba y haga que el constructor de copias sea 'privado'. ¡El primero compilará, el tercero no! – Nawaz

3
  1. Sí, Foo obj(args) crea un objeto Foo y llama al ctor una vez.

  2. obj2 no se considera un objeto temporal. Pero al igual que 1 Foo obj2 crea un objeto y llama al Foo ctor. Suponiendo que haya querido decir obj2 = Foo(args) para la línea siguiente, esta línea crea un objeto Foo temporal y luego llama al obj2.operator=(). Por lo tanto, para este segundo ejemplo, solo hay un único objeto temporal, uno no temporal, los Fooctors se llaman dos veces (una para no temporal, una para el temporal) y el operador =() se llama una vez.

  3. No, esta línea no llama al operator=(). Cuando inicializa obj3 usando la sintaxis = es casi exactamente como si hubiera usado paréntesis en su lugar: Foo obj3(Foo(args)); Entonces esta línea crea un objeto temporal y luego llama al códec Foo para inicializar obj3 usando ese objeto temporal.

1

Su terminología es un poco confusa.Los objetos obj, obj2obj3 no se denominan "objetos temporales". Solo la instancia que se crea en la línea 3 antes de ser asignada a obj es un objeto temporal.

Además, no crea "una copia de Foo", crea "una instancia de Foo" o "un objeto de tipo Foo".