2010-01-12 8 views
8

Tengo una pregunta sobre el siguiente código:Destructor virtual para boost: clases no procesables?

class MyClass : private boost::noncopyable 
{ 
    public: 

    MyClass() {} 
    virtual ~MyClass() {} 
} 

class OtherClass : private boost::noncopyable 
{ 
    private: 
    MyClass* m_pMyClass; 
} 

Mis pensamientos son que MiClase no se pueden copiar utilizando la construcción o asignación. Es necesario utilizar un destructor virtual si deseo admitir clases derivadas de MyClass, que no quiero admitir. No tengo la intención de crear punteros a esta clase y pasarlos.

No quiero un Singleton y no puedo ver un inconveniente para eliminar el destructor virtual.

¿Introduzco un problema potencial si elimino el destructor virtual para una clase no copiable? ¿Hay mejores prácticas para manejar una clase que no necesita ser Singleton, pero solo quiero una instancia en otra clase y no soporte la herencia?

+3

Si no desea apoyar la herencia, considere hacer el constructor privado y tienen una estática crear-función en su lugar. – Macke

+1

Marcus: aunque eso requiere otras cosas que no quiere admitir, como copiar o pasar punteros (la fábrica debe devolver el valor o devolver un puntero). –

Respuesta

13

No, todo el punto de un destructor virtual es que las clases derivadas pueden destruir polimórficamente. Si esto nunca será una clase base, no es necesario que sea virtual.

3

Realmente no soy un fan de la clase boost :: noncopyable en su conjunto. ¿Por qué no declarar el constructor de copias y el operador de asignación de su clase como privados y no definirlos? Eso logrará lo mismo, y puede deshacerse del destructor virtual.

Boost solo proporciona un destructor virtual para que las personas puedan pasar por boost :: objetos no procesables polimórficos y aún así hacer que se comporten bien. Técnicamente hablando, si no va a utilizar la clase polimórficamente (incluso puede heredar de ella), realmente no necesita un destructor virtual.

+1

Porque boost :: noncopyable es más legible, como se dicen ellos mismos. –

+5

boost :: noncopyable no proporciona un destructor virtual – villintehaspam

+1

La legibilidad está en el ojo del espectador –

9

La regla general es que si su clase tiene funciones virtuales, necesita un destructor virtual. Si no lo hace, pero todavía se deriva de una clase base, la clase base (y por lo tanto su clase) puede o no necesitar un destructor virtual dependiendo.

Derivar su clase de boost::noncopyable realmente no cuenta como derivada de una clase base. boost::noncopyable es más como una conveniente anotación respaldada con un par de declaraciones que harán que el compilador aplique la anotación. No es realmente una clase base en ningún sentido convencional. Nadie va a tratar de pasar un puntero a su clase como un puntero o referencia al boost::noncopyable. E incluso si lo hicieran, su destructor virtual no ayudaría porque el destructor boost::noncopyable no lo es.

Y, por último, como se señaló en un comentario, incluso está heredando de forma privada de boost::noncopyable por lo que no es realmente herencia en absoluto en lo que respecta a nadie fuera de la clase.

Así que realmente, no hay necesidad de convertirlo en un destructor virtual.

+1

Está utilizando herencia privada, desde fuera de la clase, aparecerá como no heredando de 'boost :: noncopyable' –

3

destructor virtual en la clase base se utiliza para evitar el problema de la destrucción parcial como:

Base *pBase = new Derived(); 
delete pBase; 

//if destructor is not made virtual then derived class destructor will never called. 

Al heredar una clase privada, compilador no realiza la conversión implícita de la derivada a la clase base y si está seguro de que el objeto derivado nunca se destruye usando el puntero de clase base, entonces no es necesario el destructor virtual en la clase base.

Base *pBase = new Derived(); // will flash error 
1

boost::noncopyable está destinado a decir que no desea que las copias del objeto hecho. Eres consciente de que esto es diferente de derivar del objeto.

Está perfectamente bien deshacerse del destructor virtual si nunca se derivará del objeto. Si desea aplicar la política "no derivar de este objeto", there is a way. Desafortunadamente, no hay boost::nonderivable para arreglar esto.


como se menciona en el enlace, C++ 11 permite declarar la clase final:

class MyClass : final private boost::noncopyable { ... }; 
+0

Enlace roto. Estoy interesado en. – Caduchon

+1

He actualizado el enlace. Gracias por el reporte. –

Cuestiones relacionadas