You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++函数局部变量销毁时机问询(含C++14与C++17差异)

C++局部非静态对象销毁时机解析

问题1(C++14及更早版本)

你的理解是正确的。在C++14及更早版本中,无优化情况下函数返回对象的流程是:

  1. 先基于函数内的局部对象创建返回临时对象;
  2. 临时对象构造完成后,函数的局部变量按声明逆序销毁(示例中先销毁y,再销毁x);
  3. 最后临时对象参与赋值操作,赋值完成后临时对象自身才会销毁。

这和你看到的输出完全匹配:y的析构函数先输出quitting f(),之后才执行assignment赋值操作。


问题2(C++17及更高版本)

你的猜测不完全准确,核心要结合C++17对prvalue的新规则理解:

C++17重新定义了prvalue,它不再是“临时对象的雏形”,而是直接代表对象的初始化操作。当你写return X(z);时,这个prvalue会直接将X对象构造在最终需要它的内存位置——也就是main()中用于赋值的临时对象内存,而非中间生成额外的临时对象。

具体执行流程:

  1. 调用f2()时,返回f1()的prvalue不会触发f1()局部对象提前销毁;
  2. 执行f1()的return X(z);时,X对象直接在f2()返回值对应的物化位置(即main()的赋值临时对象内存)完成构造,输出constructing X;
  3. X构造完成后,f1()的局部变量(z和Ya)按逆序销毁,输出quitting f1();
  4. 接着f2()的局部变量Yb销毁,输出quitting f2();
  5. 最后临时对象参与赋值操作,输出assignment。

关键点:函数的局部变量会在返回语句中prvalue对应的最终对象构造完成后销毁,而非prvalue传递过程中。因此z在X对象构造完成后才销毁,完全能满足X(Z)构造函数的需求,不会出现对象依赖已销毁变量的问题。

如果写成X x = f2();,f2()的prvalue会直接物化到x的内存中,同样是f1()和f2()的局部变量在各自返回语句的对象构造完成后依次销毁,之后x就完成了初始化。


内容的提问来源于stack exchange,提问作者CPPL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 15:39:37