C++ 析构顺序
C++ 中对象的析构顺序,核心原则只有一句:
构造顺序的逆序,就是析构顺序。
具体到不同场景:
-
同一作用域内的局部对象
按声明顺序构造,按相反顺序析构,像栈一样后进先出。
-
数组元素
按从前往后构造,按从后往前析构。
-
类对象内部
构造时:基类 → 成员(按声明顺序)→ 自身构造体。
析构时:自身析构体 → 成员(按声明逆序)→ 基类。
-
继承体系
派生类析构体先执行,然后派生类成员逆序析构,再析构直接基类,依次向上。
-
动态分配对象
delete p时调用p的析构函数;delete[] arr时逆序销毁数组元素。 -
静态/全局对象
程序退出时,同一编译单元内按构造逆序析构;跨编译单元顺序不确定。
-
异常栈展开
抛异常时,局部对象按构造逆序被销毁。
cpp
#include <iostream>
#include <string>
struct Tracer {
std::string name;
explicit Tracer(std::string n) : name(std::move(n)) {
std::cout << "构造 " << name << "\n";
}
~Tracer() {
std::cout << "析构 " << name << "\n";
}
};
struct Base {
Tracer base_member{"Base::member"};
Base() { std::cout << "Base 构造体\n"; }
~Base() { std::cout << "Base 析构体\n"; }
};
struct Derived : Base {
Tracer d_member1{"Derived::member1"};
Tracer d_member2{"Derived::member2"};
Derived() { std::cout << "Derived 构造体\n"; }
~Derived() { std::cout << "Derived 析构体\n"; }
};
int main() {
std::cout << "===== 局部变量 =====\n";
{
Tracer a("a");
Tracer b("b");
Tracer c("c");
}
std::cout << "\n===== 数组 =====\n";
{
Tracer arr[3] = { {"arr0"}, {"arr1"}, {"arr2"} };
}
std::cout << "\n===== 继承与成员 =====\n";
{
Derived d;
}
std::cout << "\n===== 结束 =====\n";
return 0;
}