c++析构函数的执行顺序
在C++中,析构函数的执行顺序与构造函数相反,遵循**LIFO(Last In, First Out)**原则,也就是"后构造先析构"。
基本规则:
对于你的例子:
A a1; // 先构造
A a2; // 后构造
析构顺序是:a2 先析构,a1 后析构
详细说明:
1. 局部对象的析构顺序
void function() {
A a1; // 1. 先构造
A a2; // 2. 后构造
A a3; // 3. 最后构造
} // 析构顺序:a3 → a2 → a1
2. 全局/静态对象的析构顺序
A global1; // 程序启动时构造
A global2; // 程序启动时构造
int main() {
// ...
return 0;
}
// 程序结束时析构顺序:global2 → global1
3. 类成员对象的析构顺序
class Container {
A member1; // 按声明顺序构造
A member2; // 按声明顺序构造
public:
~Container() {
// member2 先析构,member1 后析构
// 这发生在用户定义的析构函数代码执行之后
}
};
示例代码验证:
#include <iostream>
#include <string>
using namespace std;
class A {
private:
string name;
public:
A(const string& n) : name(n) {
cout << "构造: " << name << endl;
}
~A() {
cout << "析构: " << name << endl;
}
};
void testLocalObjects() {
cout << "=== 局部对象测试 ===" << endl;
A a1("a1");
A a2("a2");
A a3("a3");
cout << "即将离开函数作用域..." << endl;
}
class Container {
private:
A member1;
A member2;
public:
Container() : member1("member1"), member2("member2") {
cout << "Container构造完成" << endl;
}
~Container() {
cout << "Container开始析构" << endl;
// 注意:成员对象的析构会在这个析构函数执行完后自动进行
}
};
void testMemberObjects() {
cout << "\n=== 成员对象测试 ===" << endl;
Container c;
cout << "即将离开函数作用域..." << endl;
}
// 全局对象
A global1("global1");
A global2("global2");
int main() {
cout << "程序开始执行main函数" << endl;
testLocalObjects();
testMemberObjects();
cout << "\nmain函数即将结束" << endl;
return 0;
}
// 程序结束时,全局对象按相反顺序析构:global2 → global1
## 运行结果分析:
这个程序的输出会是:
构造: global1
构造: global2
程序开始执行main函数
=== 局部对象测试 ===
构造: a1
构造: a2
构造: a3
即将离开函数作用域...
析构: a3
析构: a2
析构: a1
=== 成员对象测试 ===
构造: member1
构造: member2
Container构造完成
即将离开函数作用域...
Container开始析构
析构: member2
析构: member1
main函数即将结束
析构: global2
析构: global1
总结:
- 局部对象:后构造先析构(栈式顺序)
- 全局/静态对象:后构造先析构
- 类成员对象:按声明顺序构造,按相反顺序析构
- 继承关系:派生类析构函数先执行,然后是基类析构函数
这种设计确保了对象依赖关系的正确处理,避免了悬空引用等问题。