c++ copy constructor

copy constructor struct c++



Copiar constructores-c++ (9)

¿Puedo escribir un constructor de copia simplemente pasando un puntero en lugar de la referencia constante? (¿Estaría bien si me aseguro de que no voy a cambiar ningún valor?)

Al igual que:

SampleClass::SampleClass(SampleClass* p) { //do the necessary copy functionality }

en lugar de:

SampleClass::SampleClass(const SampleClass& copyObj) { //do the necessary copy }

Gracias por adelantado.

Gracias a todos. Entonces, si escribo un constructor que toma un puntero (y pensé que ese es mi constructor de copia), el compilador seguiría suministrando el constructor de copia predeterminado, en cuyo caso mi constructor (que yo creía era mi constructor de copia) no sería llamado y se llamará al constructor de copia predeterminado. Lo tengo.


Sí, puede escribir un constructor que tome un puntero al objeto. Sin embargo, no se puede llamar un constructor de copia. La definición misma de un constructor de copia requiere que pase un objeto de la misma clase. Si está pasando algo más, sí, es un constructor bien, pero no un constructor de copias.


Además del hecho de que no sería un constructor de copia y el compilador generará el constructor de copia a menos que lo deshabilite explícitamente, no hay nada que ganar y mucho que perder. ¿Cuál es la semántica correcta para un constructor con un puntero nulo? ¿Qué agrega esto al usuario de su clase? (Sugerencia: nada, si quiere construir a partir de un objeto de montón, puede desreferenciar el puntero y usar el constructor de copia normal).


El constructor de copia se usa implícitamente en dos casos:

  • Cuando se pasa una instancia de su clase por valor a una función.
  • Cuando se devuelve una instancia de su clase por valor de una función.

Como han mencionado otros, puede escribir un constructor con la firma descrita (o con un puntero const), pero no se usará en ninguno de los casos anteriores.


No. Los constructores de copia deben tomar una referencia, no un puntero, si es útil para pasar por valor, etc.


Por definición, el copiador usa una referencia constante. Si bien no hay nada que le impida escribir un cursor que toma un puntero, plantea algunos problemas que no están presentes al usar una referencia, por ejemplo, ¿qué debería / podría suceder si se pasa un puntero nulo?


Puede escribir un constructor así, pero técnicamente no es un constructor de copias. Por ejemplo, los contenedores STL seguirán utilizando el constructor de copia generado por el compilador (el compilador genera uno porque no escribió uno).


Puede escribir un constructor que tome un puntero como argumento.
Pero el constructor de copia es el nombre que le damos a un constructor específico.
Un constructor que toma una referencia (preferiblemente const pero no es obligatorio) de la misma clase que un argumento simplemente se llama el constructor de copia porque esto es lo que efectivamente hace.


Un constructor de copia necesita una referencia porque un parámetro de valor requeriría hacer una copia, lo que invocaría al constructor de copia, que haría una copia de su parámetro, que invocaría al constructor de copia, que ...


Puede escribir un constructor de copia perfectamente válido y aún así poder pasar una referencia que sea NULL. Puede probar NULL, pero solo si no utiliza listas de inicialización de constructor.

Ejemplo:

MyClass::MyClass( MyClass const& MyClassCopy ) : somevar( MyClassCopy.somevar ) // <- the init list goes here. { // If MyClassCopy is NULL, the initialization above is doomed! // However we can check for NULL in the constructor body but // the initialization list must be removed ... if (&MyClassCopy == NULL ) throw( std::runtime_error("NULL pointer!")); somevar = MyClassCopy.somevar; } // I''ll now do some very dangerous programming to // demonstrate one way that a NULL can get through ... MyClass* P = NULL; MyClass A( *P ); // Bang, you''re dead!

Por lo que yo sé, no hay forma de buscar un NULL desde dentro de la lista de inicialización, así que si crees que podrías terminar con una situación en la que un NULL pasa, debes probarla en el cuerpo constructor y hacer el inicializando desde allí.

No olvides que hay algunas trampas con la función :: operator = () para tener en cuenta ...