什么时候是临时调用的析构函数

Jam*_*nco 6 c++ c++11

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

假设我有以下情况

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

void doSomething()
{
   foo f = method();
   ....
}
Run Code Online (Sandbox Code Playgroud)

假设我正在使用该标志,-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()被调用返回的临时对象的析构函数?

Wer*_*mus 8

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

在表达式的末尾调用R值(临时)的析构函数.

提供你的代码:

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

void doSomething()
{
   foo f = method();
   ....
}
Run Code Online (Sandbox Code Playgroud)

method()创建一个对象.当该对象超出范围时(在方法结束时),将调用析构函数(如果没有优化).

调用"foo f ="...导致调用foo的复制构造函数.之后表达式结束,导致返回的对象(临时)被破坏.当对象"f"的析构函数在doSomething结束时超出范围时被调用.


Bri*_*ian 8

C++ 03

当实现引入具有非平凡构造函数(12.1)的类的临时对象时,它应确保为临时对象调用构造函数.类似地,应该使用非平凡的析构函数(12.4)调用析构函数.临时对象作为评估全表达式(1.9)的最后一步被销毁,该表达式(词法上)包含创建它们的点.即使该评估以抛出异常结束,也是如此.

(12.2/3;强调我的)

有两种情况下,临时表在不同于完整表达结束时被销毁.第一个上下文是表达式作为定义对象的声明符的初始值设定项.在该上下文中,保存表达式结果的临时值将持续存在,直到对象的初始化完成.该对象从临时副本初始化; 在此复制过程中,实现可以多次调用复制构造函数; 复制后,初始化完成之前或之后,临时都会被销毁.如果通过初始化器的评估产生许多临时值,则临时值以与其构造完成相反的顺序被破坏.

(12.2/4;强调我的)

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

C++ 11

当实现引入具有非平凡构造函数(12.1,12.8)的类的临时对象时,它应确保为临时对象调用构造函数.类似地,应该使用非平凡的析构函数(12.4)调用析构函数.临时对象作为评估全表达式(1.9)的最后一步被销毁,该表达式(词法上)包含创建它们的点.即使该评估以抛出异常结束,也是如此.销毁临时对象的值计算和副作用仅与完整表达相关联,而不与任何特定子表达相关联.

(12.2/3;强调我的)

C++ 11没有明确说明用作初始化程序的临时文件在初始化完成之前一直存在.相反,在1.9/10中有一个例子:

[ 例如:

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    
  { }
}
Run Code Online (Sandbox Code Playgroud)

- 结束例子 ]

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