¿Qué es un constructor de copia en C ++?

En la página 6 de Effective C ++ de Scott Meyers, se define el término ‘copy constructor‘. He estado usando el libro de Schiltdt como mi referencia y no puedo encontrar ninguna mención de los constructores de copias. Entiendo la idea, pero ¿es esta una parte estándar de c ++? ¿Se llamará a tales constructores cuando pasen una clase por valor?

Un constructor de copia tiene la siguiente forma:

class example { example(const example&) { // this is the copy constructor } } 

El siguiente ejemplo muestra dónde se llama.

 void foo(example x); int main(void) { example x1; //normal ctor example x2 = x1; // copy ctor example x3(x2); // copy ctor foo(x1); // calls the copy ctor to copy the argument for foo } 

Sí, los constructores de copias son ciertamente una parte esencial de C ++ estándar. Lea más sobre ellos (y otros constructores) aquí (Preguntas frecuentes sobre C ++).

Si tiene un libro en C ++ que no enseña sobre constructores de copia, deséchelo. Es un mal libro.

Ver Copiar constructor en Wikipedia.

La idea básica es que los constructores de copia creen instancias nuevas copiando las existentes:

 class Foo { public: Foo(); // default constructor Foo(const Foo& foo); // copy constructor // ... }; 

Dado un caso foo , invoque el constructor de copia con

 Foo bar(foo); 

o

 Foo bar = foo; 

Los contenedores de la Biblioteca de plantillas estándar requieren que los objetos se puedan copiar y asignar, por lo que si desea usar std::vector , asegúrese de tener definido un constructor de copia apropiado y operator= si los valores predeterminados generados por el comstackdor no tienen sentido .

Se llamará al constructor de copias en los siguientes escenarios:

  • Al crear objetos nuevos a partir de un objeto existente.

     MyClass Obj1; MyClass Obj2 = Obj1; // Here assigning Obj1 to newly created Obj2 

    o

     MyClass Obj1; MyClass Obj2(Obj1); 
  • Al pasar objeto clase por valor.

     void NewClass::TestFunction( MyClass inputObject_i ) { // Function body } 

    Sobre el objeto MyClass pasado por valor. Así que copiará el constructor de MyClass llamará. Pase por referencia para evitar la invocación del constructor de copias.

  • Al devolver objetos por valor

     MyClass NewClass::Get() { return ObjMyClass; } 

    Por encima de MyClass se devuelve el valor, por lo que el constructor de copias de MyClass llamará. Pase por referencia para evitar la invocación del constructor de copias.

Copy Constructor es una parte esencial de C ++. Incluso, aunque cualquier comstackdor de C ++ proporciona un constructor de copia predeterminado, si es que no lo define explícitamente en la clase, escribimos el constructor de copia para la clase por los dos motivos siguientes.

  1. Si hay alguna asignación de memoria dinámica en la clase.
  2. Si usamos variables de puntero dentro de la clase. (de lo contrario será una copia superficial en la que 2 objetos apuntarán a la misma ubicación de memoria).

Para hacer una copia profunda, debe escribir un constructor de copia y sobrecargar al operador de asignación; de lo contrario, la copia apuntará al original, con consecuencias desastrosas.

La syntax del constructor de copias se escribiría de la siguiente manera:

 class Sample{ public: Sample (const Sample &sample); }; int main() { Sample s1; Sample s2 = s1; // Will invoke Copy Constructor. Sample s3(s1); //This will also invoke copy constructor. return 0; } 

El enlace de preguntas frecuentes de C ++ publicado por Eli es bueno y la publicación de gbacon es correcta.

Para responder explícitamente a la segunda parte de su pregunta: sí, cuando pasa una instancia de objeto por valor, el constructor de copia se usará para crear la instancia local del objeto en el ámbito de la llamada a función. Cada objeto tiene un “constructor de copia predeterminado” (gbacon alude a esto como el “comstackdor generado por defecto”) que simplemente copia cada miembro del objeto; puede que esto no sea lo que desea si las instancias de su objeto contienen punteros o referencias, por ejemplo.

En cuanto a los buenos libros para (re) aprender C ++, lo aprendí hace casi dos décadas y ha cambiado mucho desde entonces, recomiendo las versiones 1 y 2 de “Thinking in C ++” de Bruce Eckel, disponibles gratuitamente aquí (tanto en PDF como en inglés). Forma HTML):

http://www.ibiblio.org/pub/docs/books/eckel/