繁体   English   中英

函数调用中的 C++ 临时对象生命周期

[英]C++ temporary objects lifetime in a function call

当我们通过原始指针或通过引用将临时智能指针管理的对象传递给函数时,标准是否保证对象的生命周期会延长到函数生命周期?

#include <iostream>
#include <memory>

struct A {
  ~A() {
    std::cout << "~A()" << std::endl;
  }
};

std::unique_ptr<A> makeA() {
  return std::make_unique<A>();
}

void f(const A& a) {
  std::cout << "f()" << std::endl;
}

int main() {
  f(*makeA());
  return 0;
}

我希望在从unique_ptr获得原始指针后销毁由unique_ptr管理的A实例,因为它是一个临时指针并且它没有绑定到函数参数。 所以输出可能是

~A()
f()

但是 gcc 和 clang 都让它存活到函数结束,即输出是

f()
~A()

所以看起来临时智能指针并没有被销毁。

为什么A实例(位于堆中)会一直存活到函数结束? 高度赞赏对标准的一些参考。

临时变量会一直存在到创建它们的完整表达式结束(有一些生命周期延长例外),请参阅[class.temporary]/4

在您的情况下, std::unique_ptr<A>类型的临时感兴趣的对象是由makeA()创建的,而完整表达式 this 是f(*makeA());的子表达式f(*makeA()); ,所以临时的生命周期将在那个分号处结束。

unique_ptr管理的对象也只有在unique_ptr本身被销毁时才会被销毁(这就是智能指针的目的)。

有关该规则的例外情况,请参阅标准的以下段落。

从标准, [class.temporary]/4

(强调我的)

临时对象被销毁作为评估完整表达式( [intro.execution] )(词汇上)包含它们创建点的最后一步 即使该评估以抛出异常结束,也是如此。 销毁临时对象的值计算和副作用仅与完整表达式相关,与任何特定子表达式无关。

这意味着,它与绑定到函数参数的临时对象makeA() ,由makeA()构造的临时makeA()在完整表达式结束之前不会被销毁,其中包括函数f的调用。

*makeA()正在取消引用由调用makeA创建的匿名临时makeA

该标准保证匿名临时对象在函数调用中幸存下来——换句话说,当程序控制到达语句末尾时,在概念上调用~A

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM