简体   繁体   English

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

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

When we pass an object which is managed by temporary smart pointer to a function by raw pointer or by reference, does the standard guarantee that the object's lifetime will extend to the function lifetime?当我们通过原始指针或通过引用将临时智能指针管理的对象传递给函数时,标准是否保证对象的生命周期会延长到函数生命周期?

#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;
}

I would expect that the instance of A managed by unique_ptr is destroyed once the raw pointer is obtained from it, as it is a temporary and it is not bound to function arguments.我希望在从unique_ptr获得原始指针后销毁由unique_ptr管理的A实例,因为它是一个临时指针并且它没有绑定到函数参数。 So the output could be所以输出可能是

~A()
f()

But both gcc and clang make it live till the function ends, ie the output is但是 gcc 和 clang 都让它存活到函数结束,即输出是

f()
~A()

So it seems that the temporary smart pointer is not destroyed.所以看起来临时智能指针并没有被销毁。

Why does the A instance (located in the heap) live till the function end?为什么A实例(位于堆中)会一直存活到函数结束? Some reference to the standard is highly appreciated.高度赞赏对标准的一些参考。

Temporaries live until the end of the full-expression in which they were created (with some life time extension exceptions), see [class.temporary]/4 .临时变量会一直存在到创建它们的完整表达式结束(有一些生命周期延长例外),请参阅[class.temporary]/4

In your case the temporary of interest of type std::unique_ptr<A> is created by makeA() and the full-expression this is a subexpression of is f(*makeA());在您的情况下, std::unique_ptr<A>类型的临时感兴趣的对象是由makeA()创建的,而完整表达式 this 是f(*makeA());的子表达式f(*makeA()); , so the temporary's life time will end at that semicolon. ,所以临时的生命周期将在那个分号处结束。

The object that the unique_ptr manages is also destroyed only when the unique_ptr itself is destroyed (that is the purpose of the smart pointer). unique_ptr管理的对象也只有在unique_ptr本身被销毁时才会被销毁(这就是智能指针的目的)。

For exceptions to that rule, see the following paragraph of the standard.有关该规则的例外情况,请参阅标准的以下段落。

From the standard, [class.temporary]/4从标准, [class.temporary]/4

(emphasis mine) (强调我的)

Temporary objects are destroyed as the last step in evaluating the full-expression ( [intro.execution] ) that (lexically) contains the point where they were created .临时对象被销毁作为评估完整表达式( [intro.execution] )(词汇上)包含它们创建点的最后一步 This is true even if that evaluation ends in throwing an exception.即使该评估以抛出异常结束,也是如此。 The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.销毁临时对象的值计算和副作用仅与完整表达式相关,与任何特定子表达式无关。

That means, it has nothing to do with the temporary being bound to the function parameter, the temporary constructed by makeA() won't be destroyed until the full-expression ends, which includes the invocation of the function f .这意味着,它与绑定到函数参数的临时对象makeA() ,由makeA()构造的临时makeA()在完整表达式结束之前不会被销毁,其中包括函数f的调用。

*makeA() is dereferencing the anonymous temporary created by the call to makeA . *makeA()正在取消引用由调用makeA创建的匿名临时makeA

The standard guarantees that the anonymous temporary survives the function call - in other words ~A is called conceptually when program control reaches the end of the statement.该标准保证匿名临时对象在函数调用中幸存下来——换句话说,当程序控制到达语句末尾时,在概念上调用~A

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

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