终于搞懂了c++的构造和析构函数的调用顺序

构造函数:

  1. 如果有基类,则按照继承的顺序调用基类构造函数
  2. 如果有成员类,则按照声明顺序调用成员类的构造函数
  3. 自己的构造函数

话不多说,看代码:

#include<iostream>
using namespace std;
class Data       //作为下面的成员类
{
public:
	Data(int x) :x(x)
	{
		cout << "Data cons. " << endl;
	}
	~Data() { cout << "Data des. " << endl; }
private:
	int x;
};
class BaseA     //第一个基类
{
public:
	BaseA(int x) :dl(x) { cout << "BaseA cons. " << endl; }
	~BaseA() { cout << "BaseA des" << endl; }
private:
	Data dl;  	//成员类
};
class BaseB		 //第二个基类
{
public:
	BaseB(int x) :dl(x) { cout << "BaseB cons. " << endl; }
	~BaseB() { cout << "BaseB des" << endl; }
private:
	Data dl;	//成员类
};
class Derived :public BaseB,public BaseA	//注意继承顺序
{
public:
	Derived(int x) :BaseA(x),BaseB(x), d2(x) { cout << "Derived cons. " << endl; }  //注意初始化顺序 
	~Derived() { cout << "Derived des. " << endl; }
private:
	Data d2;
};
int main()
{
	Derived obj(5);
	return 0;
}

答案:
在这里插入图片描述
由此我们可以看到,基类有成员类,所以要先调用基类的成员类的构造函数,再调用基类的构造函数,按照继承顺序重复。然后子类也有成员类,所以先调用子类的成员类的构造函数,再调用自己的构造函数。

再来看看析构函数:
其实很简单!!! 就是构造函数反过来。但是有几点要注意。

  1. 一般情况下,类指针和引用在return时不会自动调用析构函数。
  2. delete指向子类对象的子类类型指针,按照规则进行。
  3. delete指向子类对象的基类类型指针时,如果基类的析构函数不是虚函数(virtual),那么只能够调用父类而不能调用子类的析构函数

没有virtual时:

#include<iostream>
using namespace std;
class Data       //作为下面的成员类
{
public:
	Data(int x) :x(x)
	{
		cout << "Data cons. " << endl;
	}
	~Data() { cout << "Data des. " << endl; }
private:
	int x;
};
class BaseA     //第一个基类
{
public:
	BaseA(int x) :dl(x) { cout << "BaseA cons. " << endl; }
	~BaseA() { cout << "BaseA des" << endl; }  //没有virtual
private:
	Data dl;  	//成员类
};
class Derived :public BaseA	
{
public:
	Derived(int x) :BaseA(x), d2(x) { cout << "Derived cons. " << endl; }  //注意初始化顺序 
	~Derived() { cout << "Derived des. " << endl; }
private:
	Data d2;
};
int main()
{
	BaseA *b=new Derived(5);
	delete b;
	return 0;
}

结果:
在这里插入图片描述
可见没有调用子类的析构函数。

有virtual时

#include<iostream>
using namespace std;
class Data       //作为下面的成员类
{
public:
	Data(int x) :x(x)
	{
		cout << "Data cons. " << endl;
	}
	~Data() { cout << "Data des. " << endl; }
private:
	int x;
};
class BaseA     //第一个基类
{
public:
	BaseA(int x) :dl(x) { cout << "BaseA cons. " << endl; }
	virtual ~BaseA() { cout << "BaseA des" << endl; }  //有virtual
private:
	Data dl;  	//成员类
};
class Derived :public BaseA	//注意继承顺序
{
public:
	Derived(int x) :BaseA(x), d2(x) { cout << "Derived cons. " << endl; }  //注意初始化顺序 
	~Derived() { cout << "Derived des. " << endl; }
private:
	Data d2;
};
int main()
{
	BaseA *b=new Derived(5);
	delete b;
	return 0;
}

结果:
在这里插入图片描述
成功通过父类指针调用子类的析构函数。

如果有不对的地方,欢迎大家批评指教!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值