c ++ - 构造和破坏的顺序

时间:2017-07-04 08:03:04

标签: c++ constructor reference destructor

我有以下C ++代码(VS2013):

iframe

它产生以下输出:

  

DEFAULT CTOR 1

     

DEFAULT CTOR 3

     

DEFAULT CTOR 2

     

COPY CTOR 3

     

DTOR 2

     

DTOR 3

     

DTOR 3

     

DTOR 1

前3个是参数构造函数(错误输出“DEFAULT CTOR”但无关紧要),在调用#include <iostream> using namespace std; class A { int i; public: A(int i) : i(i) { cout << "DEFAULT CTOR " << i << endl; } A(const A &o) : i(o.i) { cout << "COPY CTOR " << i << endl; } ~A() { cout << "DTOR " << i << endl; } friend A f(const A &, A, A *); }; A f(const A &a, A b, A *c) { return *c; } int main() { f(1, A(2), &A(3)); } 之前调用它们。

然后,当运行f行时,运行值为3的复制构造函数,然后销毁值为2的对象。

最后,在return *c;范围的末尾,剩余的对象(3,3,1)被破坏。

我不明白这种行为,并没有找到解释。

任何人都可以详细说明发生的事情的顺序吗?

具体做法是:

  1. 为什么在第二个对象main之前构造第三个对象&A(3)?这与它们的创建有关(第三个是引用,第二个是值),或者A(2)的定义方式(第二个是值,第三个是指针)?

  2. 运行f时,会创建第三个对象的副本以便返回。 然后,在返回之前被破坏的唯一对象是第二个对象。同样,这与他们的创作有关,还是与定义return *c;的方式有关?

  3. 提前致谢。

1 个答案:

答案 0 :(得分:6)

  

为什么在第二个对象A(2)之前构造第三个对象&amp; A(3)?这与它们的创建有关(第三个是引用,第二个是值),或者f的定义方式(第二个是值,第三个是指针)?

这是因为函数参数的评估顺序未被C ++标准指定。编译器可以根据需要对它们进行评估。这是许多未定义行为实例的原因,当没有意识到这一点的程序员依赖于不存在的排序时。

  

返回时* c;运行,创建第三个对象的副本以返回。然后,在返回之前被破坏的唯一对象是第二个对象。同样,这与他们的创作有关,还是与f的定义方式有关?

有点,是的。 selected对象是通过直接初始化函数selected="false"的参数创建的。函数参数的范围是函数体。因此A(2)在函数退出时就超出了范围。其他对象的生命周期稍长,因为它们是在函数外部创建的,并通过引用/指针传递。它们存在直到完整表达式f结束,因此它们将在以后被破坏。