【问题标题】:How to get virtual destructors to be called in C++?如何在 C++ 中调用虚拟析构函数?
【发布时间】:2019-06-26 22:22:00
【问题描述】:

我正在尝试查看调用属于长链层次结构的类的虚拟析构函数的效果:A 类到 E 类。

奇怪的是,析构函数不会向控制台写入任何内容。我首先认为这可能正在发生,因为 main 也正在退出。因此,我将所有测试代码放在一个名为 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;
}

【问题讨论】:

  • 我已回滚您对问题的更改,因为您不应该在问题中加入正确答案,因为答案不再有意义
  • 好的。我结合了 David 和 Basile 的建议,它奏效了。我有 unique_ptr 变量,而不是需要 new 和 delete 的裸指针,还尝试了一个局部变量 E ee。

标签: c++ c++11 virtual virtual-destructor


【解决方案1】:

您永远不会delete 您的原始指针。更喜欢智能指针而不是原始指针。

你应该添加

delete a1;
delete a2;

在您的 test 末尾附近。

也尝试创建一些 E 实例作为automatic variable(通常在调用堆栈上)。例如,插入

E ee;

在这两个delete-s之间。

【讨论】:

  • 哦!我怎么错过了!!我应该使用 unique_prt 智能指针!谢谢。
  • 那你可能应该接受我的回答(左边的绿色勾号)。
  • 答案还在新鲜出炉,烟雾还在冒出。我需要再等 9 分钟。
  • 谢谢你们俩。
  • @softwarelover 仍然需要选择一个来将您的问题标记为已解决。如果您认为这两个答案同样好,请选择之前发布的一个(这个)。
【解决方案2】:

嗯……你实际上泄露了那些。

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 在超出范围时会自动删除他们的指针。

【讨论】:

    猜你喜欢
    • 2011-08-12
    • 2011-12-06
    • 2017-08-13
    • 2015-12-30
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 2018-01-10
    • 2020-07-06
    相关资源
    最近更新 更多