c++ - temporary的析构函数什么时候调用

标签 c++ c++11

我想知道何时为 C++03 和 C++11 调用临时数组的析构函数

假设我有以下情况

foo method()
{
   foo f;
   ......
   ......
   return foo;
}

void doSomething()
{
   foo f = method();
   ....
}

假设我正在使用标志 -fno-elide-constructors 因为我想从理论上了解何时调用临时的析构函数。 因此,在 C++03 中的上述代码中,当 method() 完成时,使用其复制构造函数制作了 foo 的拷贝。之后在语句 foo f = method() 中再次调用 foo 的复制构造函数。 在这种情况下,对于 C++03,何时调用此临时对象(由 method 传递)的析构函数? 是否在 范围的末尾调用doSomething() 现在我想将相同的情况应用于涉及移动语义的 C++11。在 C++11 的情况下,当 method 返回 foo 的拷贝时。然后当 foo f = method() 被调用时foo 的构造函数被调用。 那么在 C++11 的情况下,什么时候调用从 method() 返回的临时对象的析构函数?

最佳答案

C++03

When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (12.4). Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception.

(12.2/3;强调我的)

There are two contexts in which temporaries are destroyed at a different point than the end of the full- expression. The first context is when an expression appears as an initializer for a declarator defining an object. In that context, the temporary that holds the result of the expression shall persist until the object’s initialization is complete. The object is initialized from a copy of the temporary; during this copying, an implementation can call the copy constructor many times; the temporary is destroyed after it has been copied, before or when the initialization completes. If many temporaries are created by the evaluation of the initializer, the temporaries are destroyed in reverse order of the completion of their construction.

(12.2/4;强调我的)

因此 method() 的临时结果在初始化结束时被销毁。

C++11

When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1, 12.8), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (12.4). Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. 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.

(12.2/3;强调我的)

C++11 没有明确说明用作初始化器的临时对象会一直存在到初始化完成为止。相反,1.9/10 中有一个示例:

[Example:

struct S {
  S(int i): I(i) { }
  int& v() { return I; }
private:
  int I;
};

S s1(1); // full-expression is call of S::S(int)
S s2 = 2; // full-expression is call of S::S(int)

void f() {
  if (S(3).v()) // full-expression includes lvalue-to-rvalue and
                // int to bool conversions, performed before
                // temporary is deleted at end of full-expression    
  { }
}

end example]

这大概是为了阐明当初始化具有非平凡初始化的对象时,有一个包含对其构造函数的调用的完整表达式。这消除了在 C++03 中明确说明 12.2/4 中所述内容的需要。

关于c++ - temporary的析构函数什么时候调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29375747/

相关文章:

c++ - Variadic Templates - 参数包扩展理解

c++ - 将可变数量的参数传递给构造函数

c++ - 如何在我的 Mac 上安装 boost?

c++ - Yield 从 C# 到 C++,处理容器

c++ - Eclipse 不会忘记之前的错误

c++ - 枚举器值的计算结果为 2147483648,无法将其缩小为类型 'int'

c++ - std::atomic 内存屏障可以用于在线程之间传输非原子数据吗?

c++ - 空基类构建开销?

c++ - 我是否需要通过锁来保护对 Boost MultiIndex 索引(索引本身)的访问?

c++ - 尝试 push_back() 结构会导致 2D vector 中的信息不正确