c++ virtual-destructor

Destructores predeterminados virtuales en C++



virtual-destructor (4)

La recomendación es insertar

virtual ~criterion() {}

para evitar la eliminación de un problema de puntero de clase base. De lo contrario perderá memoria ya que no se llamarán los destructores de las clases derivadas.

criterion *c = new fastFilter(); delete c; // leaks

Tengo un gran conjunto de clases heredadas (criterios) que heredan de una clase base (criterio). Aquí está el código del criterion

class criterion { public: virtual unsigned __int32 getPriorityClass() const = 0; virtual BOOL include(fileData &file) const = 0; virtual void reorderTree() = 0; virtual unsigned int directoryCheck(const std::wstring& directory) const = 0; virtual std::wstring debugTree() const = 0; };

Algunos ejemplos de clases derivadas de este:

class fastFilter : public criterion { public: void reorderTree() {}; unsigned int directoryCheck(const std::wstring& /*directory*/) const { return DIRECTORY_DONTCARE; }; unsigned __int32 getPriorityClass() const { return PRIORITY_FAST_FILTER; }; }; class isArchive : public fastFilter { public: BOOL include(fileData &file) const { return file.getArchive(); } std::wstring debugTree() const { return std::wstring(L"+ ISARCHIVE/n"); }; };

Como no tengo un destructor aquí, pero se supone que esto es una clase base, ¿necesito insertar un destructor virtual vacío, me gusta esto ?:

virtual void ~criterion() = 0;

Si se necesita esa declaración de destructor virtual, ¿todas las clases intermedias también necesitan una? Es decir, ¿el filtro rápido también necesita un destructor virtual?


No es necesario hacer que el destructor sea abstracto, solo dale una implementación vacía:

virtual ~criterion() { }

De esta manera, no está obligado a implementarlo en todas las clases secundarias, pero aún así cada una tendrá un destructor virtual (heredado).


Sí, la clase base necesita un destructor virtual, incluso si está vacío. Si no se hace eso, entonces cuando algo delete un objeto derivado a través de un puntero / referencia base, los objetos miembros del objeto derivado no tendrán la oportunidad de destruirse a sí mismos correctamente.

Las clases derivadas no necesitan declarar o definir su propio destructor a menos que necesiten algo distinto al comportamiento predeterminado del destructor.


Un pequeño cambio de lo que otros ya han respondido:

En lugar de

virtual void ~criterion() = 0;

La versión requerida es:

virtual ~criterion() {} //Note: Removed void as destructors not allowed // a return type

Para saber más sobre el destructor virtual, eche un vistazo a este enlace de Preguntas frecuentes ¿ Cuándo debería ser virtual mi destructor?