10

Esto es sólo una pregunta rápida para entender correctamente lo que sucede cuando se crea una clase con un constructor de esta manera:compilador genera constructores

class A 
{ 
    public: 
    A() {} 
}; 

sé que no se genera un constructor por defecto, ya que ya está definido, pero son los constructores de copia y asignación generados por el compilador o en otras palabras, ¿necesito declarar un constructor de copia privada y un operador de asignación privada para evitar que esto ocurra?

class A 
{ 
    private: 
    // needed to prevent automatic generation? 
    A(const A&); 
    A& operator=(const A&); 
    public: 
    A() {} 
}; 

Respuesta

10

Sí. El constructor de copia, el operador de asignación y el destructor siempre se crean independientemente de otros constructores y operadores.

Si quiere deshabilitar uno, lo que tiene allí es perfecto. Es bastante común también.

+0

De hecho, aunque si está usando esto para evitar la copia/asignación, echa un vistazo a [boost :: noncopyable] (http: // www .boost.org/doc/libs/1_55_0/libs/utility/utility.htm # Class_noncopyable). (Puedes arrancar esta clase simple o escribir la tuya y volver a usarla donde quieras). – TypeIA

13

Sí, el constructor de copias y los operadores de asignación de copias se siguen creando incluso si declara su propio constructor predeterminado.

La creación de estos solo se suprime si declara su propio constructor de copia o el operador de asignación de copia en la definición de clase, respectivamente.

en cuenta que es posible tener su propio constructor de copia, y un compilador siempre que uno:

struct A { 
    A() { } 
    A(A const&, int foo); 
}; // compiler declares a copy constructor now 

// make the second parameter have a default argument 
// now this constructor is a copy constructor too. 
inline A::A(A const&, int foo = 0) { 

} 

int main() { 
    A a; 
    A b = a; // ambiguity between compiler's one and our custom one! 
} 

Sin embargo, el estándar permite que los compiladores para aceptar este código - pero el efecto es similar a tener un comportamiento indefinido: El programa está mal formado, pero no se requiere advertencia/error para ese programa. (Las primeras versiones de GCC no rechazan este código, las más recientes lo rechazan).

+1

Tus publicaciones son "como de costumbre" muy informativas :) –

2

Si desea deshabilitar la copia y la asignación, entonces podría ser mejor heredar de una clase que tiene un constructor de copia privada y un operador de asignación (boost::noncopyable es uno ya hecho).

1) Mecanografía menos repetitiva.

2) Auto-documentación (con suerte).

3) Más fuerte comprueba que esas operaciones no se pueden invocar (la clase en sí, ni los amigos pueden hacer copias tampoco, eso daría como resultado un compilador, no un error de enlazador).

4) no ocultará el constructor por defecto :)

#include <boost/noncopyable.hpp> 

class X : boost::noncopyable 
{ 
}; 

int main() 
{ 
    X a, b;  //has default constructor 
    //X c(a); //but can't be copied 
    //a = b; //or assigned 
} 
Cuestiones relacionadas