Возможная утечка памяти без виртуального деструктора?
#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;
}
У меня нет виртуального деструктора в классе derv, он удаляет только базовую часть объекта derv?
Ответы
Ответ 1
Это может быть.
Поскольку base
не имеет виртуального деструктора, ваш код демонстрирует поведение undefined. Все может случиться. Возможно, он работает так, как вы ожидаете. Это может привести к утечке памяти. Это может привести к сбою вашей программы. Он может отформатировать ваш жесткий диск.
Была запрошена цитата. С++ 11 §5.3.5/3 гласит, что для скалярного выражения delete
(т.е. Не выражения delete[]
):
если статический тип подлежащего удалению объекта отличается от его динамического типа, статический тип должен быть базовым классом динамического типа объекта, который должен быть удален, и статический тип должен иметь виртуальный деструктор или поведение undefined.
Статический тип (base
) отличается от динамического типа (derv
), а у статического типа нет виртуального деструктора, поэтому поведение undefined.
Ответ 2
В вашем коде отсутствует утечка памяти. Если бы вам нужно было освободить некоторую память в деструкторе производного класса, была бы утечка памяти.
Ответ 3
В исходном коде отсутствует утечка памяти, так как у вас нет какой-либо переменной-члена, которая создается динамически.
Рассмотрим приведенный ниже пример. Случай 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;
}
В этом случае вывод будет,
Base Destructor called
В этом случае происходит утечка памяти, так как "b" создается динамически, используя "новый", который следует удалить с помощью ключевого слова "удалить". Поскольку derv destructor не называется, он не удаляется, поэтому происходит утечка памяти.
Рассмотрим приведенный ниже случай 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;
}
В случае выхода 2 будет
Derv Destructor called
Base Destructor called
В этом случае утечка памяти отсутствует. Если вызывающий derv destructor вызывается и b удаляется.
Деструктор может быть определен как Виртуальный в базовом классе, чтобы удостовериться, что деструктор производного класса вызывается, когда мы удаляем указатель базового класса, который указывает на производный объект класса.
Мы можем сказать: "Деструктор должен быть виртуальным, если производный класс имеет динамически созданные члены".