Как заставить виртуальные деструкторы вызываться в C ++? - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь увидеть эффект от вызова виртуальных деструкторов классов, принадлежащих к длинной цепочке иерархии: от класса A к классу E.

Странно, деструкторы ничего не записывают в консоль.Сначала я подумал, что, возможно, это происходит, потому что главное тоже выходило.Итак, я поместил весь тестовый код в функцию с именем test () и вызвал ее из main (), чтобы при возвращении test я видел следы деструктора.Но ничего!На консоли не отображаются знаки «cout»!

#include <iostream>

using namespace std;

//A constructor cannot be virtual but a destructor can.
class A {
public:
A() {
    cout << "A constructor" << endl;
}
virtual ~A() {cout << "A destructor" << endl;}
};

class B :public A {
public:
    B() {
    cout << "B constructor" << endl;
    }
    virtual ~B() {cout << "B destructor" << endl;}
};

class C :public B {
public:
    C() {
    cout << "C constructor" << endl;
    }
    virtual ~C() {cout << "C destructor" << endl;}
};

class D :public C {
public:
    D() {
    cout << "D constructor" << endl;
    }
    ~D() {cout << "D destructor" << endl;}
};

class E :public D {
public:
    E() {
     cout << "E constructor" << endl;
      }
     ~E() {cout << "E destructor" << endl;}
};

void test() {
   cout << "Test1 begins..." << endl;
   A* a1 = new D();
   cout << "Test2 begins..." << endl;
   A* a2 = new E();
}

int main() {
 test();
 return 0;
}

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Ммм ... ты на самом деле утечешь.

Каждый объект возражения, созданный ключевым словом new, должен иметь эквивалентное значение delete:

void test() {
   cout << "Test1 begins..." << endl;
   A* a1 = new D();
   cout << "Test2 begins..." << endl;
   A* a2 = new E();
   delete a1;
   delete a2;
}

Разработчики (только в вашем случае) всегда забывали удалять динамически размещаемые объекты, поэтому умные указателибыли введены:

void test() {
   cout << "Test1 begins..." << endl;
   std::unique_ptr<A> a1(new D());
   cout << "Test2 begins..." << endl;
   std::unique_ptr<A> a2(new E());
}

не нужно беспокоиться об утечке, так как unique_ptr автоматически удаляет их pointee, когда они выходят из области видимости.

0 голосов
/ 02 февраля 2019

Вы никогда не delete ваши сырые указатели.Предпочитаю умные указатели необработанным.

Вы должны добавить

delete a1;
delete a2;

в конце вашего test.

Попробуйте также создать несколько экземпляров E как автоматическая переменная (обычно в стеке вызовов).Например, вставьте

E ee;

между этими двумя delete -s.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...