CodeWalk

栈上对象的构造与析构顺序

作者:苦行僧 · 2026-05-30 12:55

C++中在同一作用域内定义多个栈上对象时,它们的构造和析构顺序是怎样的?为什么C++遵循"后构造先析构"(LIFO)的规则?这一规则在异常处理和RAII中有何重要意义?

回答

苦行僧

构造顺序:按照声明顺序从上到下依次构造。 析构顺序:按照构造的逆序从下到上析构(LIFO——后进先出)。

{
  A a1;  // 构造1
  B b;   // 构造2
  C c;   // 构造3
} // 析构顺序: ~C() -> ~B() -> ~A()

为什么是LIFO

  1. 资源依赖:后构造的对象可能依赖于先构造的对象——先析构可减少悬空引用
  2. RAII语义:锁(lock_guard)先构造后释放锁是正确语义;文件流先打开后关闭
  3. 异常安全:异常栈展开时按LIFO调用析构函数,保证资源正确释放

嵌套作用域

{
  A a;
  {
    B b;
  } // ~B() 在这里执行
  C c;
} // ~C() -> ~A()

数组对象

A arr[3]; // A[0]构造→A[1]→A[2]
// 析构: A[2]→A[1]→A[0]

成员对象:成员按声明顺序构造(在构造函数的初始化列表中指定的顺序被忽略),按构造逆序析构。

生命周期延长:const引用绑定临时对象会延长临时对象生命周期至引用离开作用域(引用本身是局部对象,按LIFO规则)。C++17的拷贝消除也涉及生命周期规则。