online ejemplos descargar definicion caracteristicas c++

ejemplos - Destructores para clases de interfaz C++



c++ online (6)

Entonces, la pregunta: cuando creas clases de interfaz como las anteriores, ¿siempre incluyes un destructor virtual? ¿Por qué? (¿Es un estilo o un error de codificación?)

Bueno, depende realmente. Si alguna vez llama a eliminar en un puntero de IBatch, probablemente no hará lo que está esperando. Por supuesto, si tiene algo como Inicial / Apagado virtual o AddRef / Lanzamientos, entonces no es realmente un problema.

Comenzando a usar PC-Lint en una base de código existente (miedo y temor).

Una cosa de la que se queja es lo siguiente:

class IBatch { public: virtual void StartBatch() =0; virtual int CommitBatch() =0; };

Que cuando otra clase deriva de esto para usarlo como una interfaz.

base class ''IBatch'' has no destructor

Entonces, la pregunta: cuando creas clases de interfaz como las anteriores, ¿siempre incluyes un destructor virtual? ¿Por qué? (¿Es un estilo o un error de codificación?)

EDITAR: Debería haber dicho que no espero ni deseo que el usuario de IBatch se destruya, solo son consumidores de un servicio, a través de esta interfaz a alguna clase de implementación externa (si eso hiciera una diferencia)



El compilador coloca el destructor predeterminado que no es virtual, lo que implica que una "eliminación" en un puntero a la clase base virtual tendrá éxito con una pérdida de memoria resultante. Por lo tanto, es un defecto de implementación, ni de estilo ni de error de codificación.


Si hay funciones virtuales, tiene que haber un destructor virtual. Siempre. No importa que sea solo una clase de interfaz, todavía necesita el destructor virtual.

O eso, o necesita un destructor no virtual protected . Pero entonces no puede eliminar el objeto utilizando el puntero de la interfaz.


Una clase con funciones virtuales pero sin destructor virtual es sospechosa, y lo más probable es que esté equivocada: vea una explicación buena y más precisa here .


Error de codificación: el destructor de su clase derivada nunca será llamado si se le llama a través de un puntero a la clase base.

Cuando implementas IBatch y te refieres a tu clase derivada por un puntero a una clase base (puntero a IBatch ) y llamas a delete en ese puntero a la clase base, podrías terminar con una pérdida de memoria porque el destructor de tu clase derivada nunca obtendrá llamado.

La regla básica es que cuando una clase tiene al menos un método virtual , necesita tener virtual destructor virtual .

class IBatch { public: virtual void f() = 0; }; class A : public IBatch { public: void f() {} ~A() {} }; IBatch * a = new A(); a->f(); // calls A::f() delete a; // calls IBatch::~IBatch() not A::~A()