【C++】构造函数 析构函数 调用顺序

微信搜索:编程笔记本。获取更多干货!
微信搜索:编程笔记本。获取更多干货!

点击上方蓝字关注我,我们一起学编程
欢迎小伙伴们分享、转载、私信、赞赏

今天我们来探讨一下类继承中的构造函数和析构函数的调用顺序问题。

#include <bits/stdc++.h>

using namespace std;

class Father {
public:
	Father() {
		cout << "Father constructor worked\n" << endl;
	}
	~Father() {
		cout << "Father destructor worked\n" << endl;
	}
};

class Son : public Father {
public:
	Son() {
		cout << "Son constructor worked\n" << endl;
	}
	~Son() {
		cout << "Son destructor worked\n" << endl;
	}
};


int main()
{
	Son son;
	
    return 0;
}

微信搜索:编程笔记本。获取更多干货!
微信搜索:编程笔记本。获取更多干货!

上面的代码中,Son 公有继承 Father ,当我们定义一个 Son 的对象时,基类和派生类的构造函数与析构函数调用顺粗如下:

Father constructor worked

Son constructor worked

Son destructor worked

Father destructor worked

可以看到,构造函数是从基类向派生类逐层调用的,析构函数是从派生类向基类逐层调用的。

问了更好地说明问题,我们增加一个类:

#include <bits/stdc++.h>

using namespace std;

class GrandFather {
public:
	GrandFather() {
		cout << "GrandFather constructor worked\n" << endl;
	}
	~GrandFather() {
		cout << "GrandFather destructor worked\n" << endl;
	}
};

class Father : public GrandFather {
public:
	Father() {
		cout << "Father constructor worked\n" << endl;
	}
	~Father() {
		cout << "Father destructor worked\n" << endl;
	}
};

class Son : public Father {
public:
	Son() {
		cout << "Son constructor worked\n" << endl;
	}
	~Son() {
		cout << "Son destructor worked\n" << endl;
	}
};


int main()
{
	Son son;
	
    return 0;
}

/*
运行结果:

GrandFather constructor worked

Father constructor worked

Son constructor worked

Son destructor worked

Father destructor worked

GrandFather destructor worked
*/

微信搜索:编程笔记本。获取更多干货!
微信搜索:编程笔记本。获取更多干货!

构造函数调用顺序:从长辈到小辈;析构函数调用顺序:从小辈到长辈。

同样地,生成对象数组与生成单个对象的情况相同,不再赘述,附上测试代码。

#include <bits/stdc++.h>

using namespace std;

class GrandFather {
public:
	GrandFather() {
		cout << "GrandFather constructor worked\n" << endl;
	}
	~GrandFather() {
		cout << "GrandFather destructor worked\n" << endl;
	}
};

class Father : public GrandFather {
public:
	Father() {
		cout << "Father constructor worked\n" << endl;
	}
	~Father() {
		cout << "Father destructor worked\n" << endl;
	}
};

class Son : public Father {
public:
	Son() {
		cout << "Son constructor worked\n" << endl;
	}
	~Son() {
		cout << "Son destructor worked\n" << endl;
	}
};


int main()
{
	Son *pSon = new Son[2];
	delete[] pSon;
	
    return 0;
}

/*
运行结果:

GrandFather constructor worked

Father constructor worked

Son constructor worked

GrandFather constructor worked

Father constructor worked

Son constructor worked

Son destructor worked

Father destructor worked

GrandFather destructor worked

Son destructor worked

Father destructor worked

GrandFather destructor worked
*/

在上面的例子中,若 delete pSon 的话,会报 munmap_chunk(): invalid pointer, Aborted (core dumped) 错误。

总结

对于具有继承关系的类,其构造函数的调用顺序是:先基类、再派生类;其析构函数的调用顺序是:先派生、后基类。

微信搜索:编程笔记本。获取更多干货!
微信搜索:编程笔记本。获取更多干货!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值