objetos ¿Cuál es la forma más confiable de prohibir un constructor de copia en C++?




destructor c++ (5)

A veces es necesario prohibir un constructor de copia en una clase de C ++ para que la clase se convierta en "no copiable". Por supuesto, operator= debería estar prohibido al mismo tiempo.

Hasta ahora he visto dos formas de hacer eso. La forma 1 es declarar el método como privado y no darle ninguna implementación:

class Class {
//useful stuff, then
private:
    Class( const Class& ); //not implemented anywhere
    void operator=( const Class& ); //not implemented anywhere
};

La forma 2 es declarar el método como privado y darle la implementación "vacía":

class Class {
//useful stuff, then
private:
    Class( const Class& ) {}
    void operator=( const Class& ) {}
};

IMO, el primero es mejor, incluso si hay alguna razón inesperada que conduzca al llamado al constructor de copia desde la misma función de miembro de la clase, habrá un error de enlazador más adelante. En el segundo caso, este escenario no se detectará hasta el tiempo de ejecución.

¿Hay algún inconveniente serio en el primer método? ¿Cuál es una mejor manera si hay alguna y por qué?


Answer #1

El primero es mejor

Aún mejor es C ++ 0x palabra clave 'eliminar' :

class Class {
// useful stuff, then
public:
    Class(const Class&) = delete;
    void operator=(const Class&) = delete;
};

Answer #2

No hay inconveniente en su primer enfoque, lo he estado usando para hacer una clase "no copiable".


Answer #3

El primer método es cómo Boost lo resuelve ( boost.org/doc/libs/1_46_1/boost/noncopyable.hpp ), hasta donde yo sé, no hay inconvenientes. De hecho, los errores del enlazador son la gran ventaja de ese método. Desea que los errores estén en tiempo de enlace, no cuando su cliente está ejecutando su código y de repente se bloquea.

En caso de que esté utilizando Boost, puede ahorrarse algo de tipeo. Esto hace lo mismo que tu primer ejemplo:

#include <boost/utility.hpp>

class Class : boost::noncopyable {
// Stuff here
}

Answer #4

Personalmente, creo que ha respondido su propia pregunta y debería usar el primer enfoque.

Si no desea que se pueda copiar, como dijo, generará un error de enlazador. Sin embargo, si utilizas el segundo método y terminas utilizando el constructor de copias por accidente, SE COMPARARÁ y se ejecutará; y no tendrá absolutamente ninguna indicación de dónde salió la inconsistencia hasta que abra un depurador. O como dijo, si puede usar un compilador moderno, use la notación '= delete' de C ++ 11.


Answer #5

Siempre puede heredar de boost::noncopyable .

De lo contrario, nunca he visto una razón por la que el número 2 sea mejor que el número 1, ya que le permitirá "copiar y construir" un objeto dentro de los métodos friend o class, aunque en realidad no cree una copia verdadera del objeto.





copy-constructor