11
#include <iostream> 
using namespace std; 
class base 
{ 
    int a; 
public: 
    base() {a =0;} 
}; 
class derv :public base 
{ 
    int b; 
    public: 
    derv() {b =1;} 
}; 
int main() 
{ 
    base *pb = new derv(); 
    delete pb; 
} 

no tengo un destructor virtual en la clase derv, ¿se elimina sólo una parte de base del objeto derv ??Posible pérdida de memoria sin un destructor virtual?

+0

Es la clase base que necesita un destructor virtual. – Yuushi

+0

@Mysticial: James tiene este. – Puppy

+0

@James, ¿Dijo que incluso la clase base no tiene ninguna función virtual, pero debe tener un destructor virtual si queremos heredar la clase base? – Alok

Respuesta

19

Podría.

Debido base no tiene un destructor virtual, su código exhibe un comportamiento indefinido. Cualquier cosa puede pasar Puede parecer que funciona como esperabas. Podría perder memoria. Podría hacer que tu programa falle. Puede formatear tu disco duro.

Se solicitó una cita. C++ 11 §5.3.5/3 establece que, para un delete expresión escalar (es decir, no una expresión delete[]):

si el tipo estático del objeto que ha de suprimirse diferente de su tipo dinámico, el tipo estático debe ser una clase base del tipo dinámico del objeto a eliminar y el tipo estático tendrá un destructor virtual o el comportamiento no está definido.

El tipo estático (base) es diferente del tipo dinámico (derv) y el tipo estático no tiene un destructor virtual, de modo que el comportamiento no está definido.

+2

La falta de destructor virtual en la base significa que cualquier finalización personalizada especificada en el destructor de las clases derivadas no se ejecutará. La memoria para el objeto todavía se desasignará correctamente. (El destructor de 'base' también sería llamado si estuviera definido por no-virtual). – Xion

+6

@Xion: Realmente. El comportamiento no está definido. Todas las apuestas están cerradas. No se puede decir nada con certeza sobre el comportamiento del programa. –

+2

referencia, por favor! – wilhelmtell

-1

No hay pérdida de memoria en el código. Hubiera habido una pérdida de memoria si necesita liberar algo de memoria en el destructor de clase derivado.

+6

El comportamiento no está definido. Todas las apuestas están cerradas. No se puede decir nada con certeza sobre el comportamiento del programa. –

-1

En su código fuente no hay pérdida de memoria, ya que no tiene ninguna variable miembro que se crea de forma dinámica.

Considere el ejemplo modificado debajo Caso 1:

#include <iostream> 
using namespace std; 
class base 
{ 
    int a; 
public: 
    base() {a =0;} 
    ~base() 
    { 
     cout<<"\nBase Destructor called"; 

    } 
}; 
class derv :public base 
{ 
    int *b; 

    public: 
    derv() { b = new int;} 
    ~derv() 
    { 
     cout<<"\nDerv Destructor called"; 
     delete b; 
    } 
}; 
int main() 
{ 
    base *pb = new derv(); 
    delete pb; 
} 

En este caso será la salida,

Base Destructor called 

En este caso no es una pérdida de memoria, porque se crea 'b' dinámicamente usando 'nuevo' que debería eliminarse usando la palabra clave 'eliminar'. Como derv destructor no se está llamando, no se elimina, por lo que hay pérdida de memoria.

Consideremos el siguiente caso 2:

#include <iostream> 
using namespace std; 
class base 
{ 
    int a; 
public: 
    base() {a =0;} 
    virtual ~base() 
    { 
     cout<<"\nBase Destructor called"; 

    } 
}; 
class derv :public base 
{ 
    int *b; 

    public: 
    derv() { b = new int;} 
    ~derv() 
    { 
     cout<<"\nDerv Destructor called"; 
     delete b; 
    } 
}; 
int main() 
{ 
    base *pb = new derv(); 
    delete pb; 
} 

En el caso de salida será de 2,

Derv Destructor called 
Base Destructor called 

En este caso no hay memoria leak.because destructor derv se llama yb es cada vez borrado

Destructor se puede definir como virtual en la clase base para asegurarse de que el destructor clase derivada que se llamará cuando borramos puntero de clase base que está apuntando al objeto de la clase derivada.

Podemos decir 'Destructor debe ser virtual cuando se derivan de clase ha creado dinámicamente miembros'.

+1

El comportamiento no está definido. Todas las apuestas están cerradas. No se puede decir nada con certeza sobre el comportamiento del programa. –

+1

@JamesMcNellis: En el código anterior que tiene asignación de memoria en la clase derivada debe tener destructor virtual. De lo contrario, hay una pérdida de memoria. –