在这个问题中:How do virtual destructors work?
最佳答案如下:
Note that the destructor of the base class will be called implicitly after the destructor of the derived class finishes. This is a difference to the usual virtual functions.
我整理了一个快速示例程序来测试它,
class A {
public:
virtual ~A() {
std::cout << "A DESTRUCTOR" << std::endl;
}
};
class B {
public:
virtual ~B() {
std::cout << "B DESTRUCTOR" << std::endl;
}
};
class C {
public:
virtual ~C() {
std::cout << "C DESTRUCTOR" << std::endl;
}
};
int main(int argc, char** argv)
{
A * aPtr = (A *)new C();
C * cPtr = new C();
delete aPtr;
delete cPtr;
return 0;
}
我得到的输出是
C DESTRUCTOR
C DESTRUCTOR
这似乎与说明不符。
我的问题是,如何在需要运行多个析构函数的类层次结构中安全地实现析构函数?
例如,假设A类和C类都在堆上分配了一个属性并需要清理它们。我怎样才能安全地编写这样的层次结构?注意:我目前没有尝试编写这样的层次结构,请不要回答“不要设计错误”#34;。此外,我理解智能指针可以解决问题,这更多的是确保我理解底层机制。
是否需要C类正确清理A类属性?如果该属性是私有而不是受保护或公开,会发生什么?我错过了什么,或者误解了我所看到的东西吗?
用于运行这些测试的编译器
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
答案 0 :(得分:4)
您忘记了类之间的继承
只要您执行delete
行
A * aPtr = (A *)new C();
我相信this就是您要搜索的内容
class A {
public:
virtual ~A() {
std::cout << "A DESTRUCTOR" << std::endl;
}
};
class B : public A{
public:
virtual ~B() {
std::cout << "B DESTRUCTOR" << std::endl;
}
};
class C : public B{
public:
virtual ~C() {
std::cout << "C DESTRUCTOR" << std::endl;
}
};
int main(int argc, char** argv)
{
A * aPtr = new C(); // The cast here is not needed
C * cPtr = new C();
delete aPtr;
delete cPtr;
return 0;
}
输出
C DESTRUCTOR
B DESTRUCTOR
A DESTRUCTOR
C DESTRUCTOR
B DESTRUCTOR
A DESTRUCTOR
答案 1 :(得分:4)
正如其他人所说,你希望(确实需要)在这里使用继承。
他们没有注意到的是编译器只允许你这样做,因为你在 不应该拥有的地方使用了一个演员表。如果您需要使用演员表,那么真的应该坐下来,三思而后行为什么该演员表是必要的,并确保它所做的是真的你想做的事。
如果没有强制转换,编译器会阻止您的代码被破坏。如果继承得到纠正,没有演员就可以了:
#include <iostream>
class A {
public:
virtual ~A() {
std::cout << "A DESTRUCTOR" << std::endl;
}
};
class B : public A {
public:
virtual ~B() {
std::cout << "B DESTRUCTOR" << std::endl;
}
};
class C : public B {
public:
virtual ~C() {
std::cout << "C DESTRUCTOR" << std::endl;
}
};
int main(int argc, char** argv) {
A * aPtr = new C();
delete aPtr;
}
结果:
C DESTRUCTOR
B DESTRUCTOR
A DESTRUCTOR
答案 2 :(得分:0)
更改为:
class A {
public:
virtual ~A() {
std::cout << "A DESTRUCTOR" << std::endl;
}
};
class B : public A{
public:
virtual ~B() {
std::cout << "B DESTRUCTOR" << std::endl;
}
};
class C : public B{
public:
virtual ~C() {
std::cout << "C DESTRUCTOR" << std::endl;
}
};
答案 3 :(得分:0)
您在此处引用的行为是派生类中虚拟析构函数的行为,这意味着具有其他类继承的类。
还记得使用g ++进行c ++编译。