Подтвердить что ты не робот

Возможная утечка памяти без виртуального деструктора?

#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?

4b9b3361

Ответ 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 удаляется.

Деструктор может быть определен как Виртуальный в базовом классе, чтобы удостовериться, что деструктор производного класса вызывается, когда мы удаляем указатель базового класса, который указывает на производный объект класса.

Мы можем сказать: "Деструктор должен быть виртуальным, если производный класс имеет динамически созданные члены".