C++ 详谈继承体系下的构造函数和析构函数

前言

前面呢, 我们说了C++中实现多态的原理, 其中也说了, 虚函数表和虚函数指针的创建时机, C++ 详谈多态实现原理-优快云博客 , 这一节呢, 我们会说说在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的赋值, 就能正常的调用到虚构造函数了~~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值