析构函数
如果类没有定义析构函数,那么只有在类内带的成员对象有析构或者类的父类有析构的情况下,编译器才会自动合成一个析构函数来,否则析构函数不会被合成。与是否含有虚接口无关。
如果编译器合成出一个析构函数,其唯一任务就是调用父类或者成员对象的析构函数,如果我们提供了一个析构函数,那么编译器会扩张它,使他调用父类或者成员对象的析构函数(在我们提供的代码之后,这个与构造函数被拓展的顺序相反)
析构顺序:
1、 本类的析构函数首先被执行
2、如果成员对象有析构函数,那么他们会以声名顺序相反的次序被调用
3、如果类对象有vptr,则现在被重新设定,指向适当的base class的 virtual table
4、如果非虚基类有析构,他们会以继承的顺序相反顺序调用
5、如果虚基类有析构,他们会以继承的顺序相反顺序调用
class D {
public:
virtual ~D() { cout << " ~D " << endl; }
virtual void func() = 0;
};
class A : public D{
public:
virtual void func() {}
virtual void foo() = 0;
};
class B : public A {
public:
void foo() {}
~B() { cout << "~B" << endl; }
};
void play()
{
A* pa = new B();
delete pa;
}
编译器会为A生成一个析构函数,输出:
~B
~D
但是,如果D类和A类都没有虚析构函数,那么就会报告警:
warning: deleting object of abstract class type ‘A’ which has non-virtual destructor will cause undefined behavior [-Wdelete-non-virtual-dtor]
delete pa;
析构的顺序是 B A D

浙公网安备 33010602011771号