全局、静态、局部静态对象的生命周期

void foo() {
    auto d = new D();
    E e1;
    {E e2;}
    E e3;
    static F f;
    delete d;
}

A a;
namespace bar {
B b;
}

int main() {
    G g;
    foo();
}

static C c;

执行结果

构造顺序: a b c g d e1 e2 e3 f
析构顺序: e2 d e3 e1 g f c b a

解析

  • 在所有函数之外定义的 a、b、c,都是在 main() 开始执行之前,按照出现的顺序依次构造 a、b、c(无论是否在命名空间中,无论是否有 static 修饰)
  • main() 函数开始执行,在栈中构造自动(局部非 static)对象 g
  • 程序调用 foo(),按顺序先在堆中构造 d,然后在栈中构造自动变量 e1
  • 继续执行,在栈中构造自动变量 e2,e2 作用域结束,析构 e2
  • 在栈中构造自动变量 e3
  • 局部静态对象 f,在程序控制路径经过时才构造(创建),但是和全局对象 a、b、c 一样,会提前在 .data/.bss 段预留空间
  • 继续按照代码控制路径,析构 ~d
  • foo() 函数结束,析构自动对象 e3,e1,析构顺序与构造顺序相反
  • main() 函数结束,析构自动对象 ~g
  • 对于局部静态/全局对象 a、b、c、f,其生命周期直到程序结束,在 main() 函数结束之后才开始析构,其析构顺序与构造顺序相反 ~f ~c ~b ~a

验证

https://godbolt.org/z/976W7jaeM (进阶!涉及到函数形参)

posted @ 2023-03-11 07:43  Zijian/TENG  阅读(102)  评论(0编辑  收藏  举报