2012-02-23 20 views
6

Estoy escribiendo una clase abstracta que será un padre para varias otras clases. Estoy pensando que el constructor de copias debería hacerse privado porque estás usando una clase abstracta y no hay nada que copiar. Sin embargo, no estoy 100% seguro.Debe copiar el constructor sea privado o público

¿Estoy en lo correcto y si no soy así, por qué debería ser público o estar protegido?

Respuesta

8

El constructor de copia debe ser privado si no desea que se copien objetos de la clase. De lo contrario, debe ser público.

+0

Es imposible para el constructor de la clase base hacer una copia de una clase derivada, por lo que no entiendo cuándo tendría sentido que sea pública. –

+0

@MarkRansom Quise decir algo como [esto] (http://ideone.com/n2ndl), pero las personas aún podían implementar el constructor de copias en la clase derivada. –

+0

Gracias, pensé que sí. Una pregunta de seguimiento, porque es privada y nunca se usará, no es necesario que haya código en el constructor de copia porque nunca se usará. ¿Es eso correcto? – Aaron

3

Al hacer que el constructor de copias sea privado, ayudará a evitar el corte inadvertido de objetos, donde se realiza una copia de una clase derivada pero se pierden todas las propiedades de esa clase derivada. Las clases derivadas pueden hacer que sus propios constructores de copia sean públicos y hagan lo correcto.

Hay un caso en el que el constructor de copia debe estar protegido en lugar de privado, cuando la clase abstracta tiene miembros de datos. Esto no sucede muy a menudo. La clase base puede copiar los miembros de la clase base mientras que la clase derivada copia sus propios miembros.

class AbstractBase 
{ 
public: 
    AbstractBase(const std::string &init) : wtf(init) {} 
    virtual ~AbstractBase() {} 
    void DoSomething() = 0; 
protected: 
    AbstractBase(const AbstractBase &r) : wtf(r.wtf) {} 

    const std::string wtf; 
}; 

class Derived : public AbstractBase 
{ 
public: 
    // ... 
    Derived(const Derived &r) : AbstractBase(r), moredata(r.moredata) {} 
private: 
    int moredata; 
}; 
+0

¡Tienes razón! Pensé que el constructor de copia de la clase base se llamaba por defecto. Aparentemente tienes que llamarlo explícitamente. ¡Qué error! –

+0

¿No se impide que la clase base sea abstracta? –

+0

@FredLarson, facepalm! Por supuesto, no puedes instanciar una clase abstracta. –

6

creo protected es la mejor opción: se deja la decisión sobre si es o no el objeto es copiable a las clases derivadas, mientras prohibiendo la copia a nivel de clase abstracta, evitando la temida object slicing.

+0

Creo que la diferencia entre protegido y privado es irrelevante en este caso, ya que el constructor de copia de la clase base estará vacío y no será necesario llamarlo. –

+1

@MarkRansom Creo que es una buena idea llamar al constructor de copias de la clase base incluso si está seguro de que está actualmente vacía. El compilador lo optimizará siempre que el constructor de copia en la clase base permanezca vacío, pero si alguien refactoriza la base para incluir un constructor de copia no vacío, las clases derivadas no necesitarían cambiar. – dasblinkenlight

+0

Muy buen punto. He editado mi propia respuesta para incluir esa posibilidad. –

Cuestiones relacionadas