析构函数

如果类没有定义析构函数,那么只有在类内带的成员对象有析构或者类的父类有析构的情况下,编译器才会自动合成一个析构函数来,否则析构函数不会被合成。与是否含有虚接口无关。

如果编译器合成出一个析构函数,其唯一任务就是调用父类或者成员对象的析构函数,如果我们提供了一个析构函数,那么编译器会扩张它,使他调用父类或者成员对象的析构函数(在我们提供的代码之后,这个与构造函数被拓展的顺序相反)

析构顺序:
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

 

posted @ 2020-05-07 11:21  ren_zhg1992  阅读(524)  评论(0)    收藏  举报