C++ 详谈继承体系下的构造函数和析构函数
前言
前面呢, 我们说了C++中实现多态的原理, 其中也说了, 虚函数表和虚函数指针的创建时机, C++ 详谈多态实现原理-CSDN博客 , 这一节呢, 我们会说说在C++中继承体系下的另一个知识点, 那就是: 继承体系下的构造函数和析构函数~~, 主要围绕两个问题: 执行顺序? 虚析构函数的作用?
继承体系下的构造函数和析构函数的执行顺序
首先我们用一句话来概括, 之后再做详细解释: 继承下, 构造函数按照依赖链(孩子依赖父亲), 从上往下构造, 析构函数按照依赖链, 从下向上析构.
我们从两个角度来探讨, 单继承 和 多继承.
单继承
我们现在在前面代码的基础上添加两个类, Base1和Drive1, Base1作为Base类中的成员变量, Drive1作为Drive中的成员变量, 我们可以设想一些这个情况下的调用顺序, 构造Drive之前要先构造Base 和 构造Drive1, 构造Base之前要先构造Base1, 所以其构造顺序应该是: Base1, Base, Drive1, Drive, 其析构顺序应该是: Drive, Drive1, Base, Base1
#include <iostream>using namespace std;class Base1
{
public:Base1(){cout << "Base1 construction" << endl;}~Base1(){cout << "Base1 destruction" << endl;}
};
class Drive1
{
public:Drive1(){cout << "Drive1 construction" << endl;}~Drive1(){cout << "Drive1 destruction" << endl;}
};
class Base
{
public:Base(){cout << "Base construction" << endl;}~Base(){cout << "Base destruction" << endl;}
private:Base1 b1;
};
class Drive : public Base
{
public:Drive(){cout << "Drive construction" << endl;}~Drive(){cout << "Drive destruction" << endl;}
private:Drive1 d1;
};
int main()
{Drive d;cout << "------------------" << endl;return 0;
}
成员类按照顺序构造, 优先于类的构造, 按照相反顺序析构.
多继承
现在, 代码有 一个MBase1和MBase2, 一个MDrive多继承自MBase1和MBase2, 并且MDrive中还有成员变量, MDrive1和MDrive2类型的变量, 构造顺序是继承的顺序
#include <iostream>using namespace std;class MBase1
{
public:MBase1(){cout << "MBase1 construction" << endl;}~MBase(){cout << "MBase1 destruction" << endl;}
};
class MBase2
{
public:MBase2(){cout << "MBase2 construction" << endl;}~MBase2(){cout << "MBase2 destruction" << endl;}
};
class MDrive1
{
public:MDrive1(){cout << "MDrive1construction" << endl;}~MDrive1(){cout << "MDrive1destruction" << endl;}
};
class MDrive2
{
public:MDrive2(){cout << "MDrive2 construction" << endl;}~MBase(){cout << "MDrive2 destruction" << endl;}
};
class MDrive : public MBase1, MBase2
{
public:MDrive(){cout << "MDrive construction" << endl;}~MDrive(){cout << "MDrive destruction" << endl;}
private:MDrive1 md1;MDrive2 md2;
};
int main()
{MDrive md;cout << "------------------" << endl;return 0;
}
多继承中, 除了前面单继承中的构造顺序, 基类是声明顺序构造, 相反顺序析构, 上面这一段代码就是, 先构造MBase1, 再构造MBase2, 再构造MDrive1和MDirve2, 最后构造MDrive.
虚析构函数的作用
作用: 在继承下, 为了使子类析构函数能够得到正常调用, 需要将基类的析构函数设置为虚析构函数.
C++中, 当一个类要被作为基类被继承是, 应该将这个基类的析构函数手动设置为虚析构函数, 之前说过, C++中如果一个方法是virtual修饰的, 那么在子类继承之后重写这个方法, 也是virtual修饰的, C++会将所有的析构函数名称修改成同一个.
这样如果父类的析构函数是虚析构函数, 子类中一定是有同名的虚的析构函数, 这样经过两次vptr的赋值, 就能正常的调用到虚构造函数了~~