Gil*_*Gil 3 c++ constructor destructor reference
我有以下C++代码(VS2013):
#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));
}
Run Code Online (Sandbox Code Playgroud)
它产生以下输出:
DEFAULT CTOR 1
DEFAULT CTOR 3
DEFAULT CTOR 2
COPY CTOR 3
DTOR 2
DTOR 3
DTOR 3
DTOR 1
前3个是参数构造函数(错误输出"DEFAULT CTOR"但无关紧要),它们在调用之前调用f.
然后,当return *c;运行该行时,将运行值为3的复制构造函数,然后销毁值为2的对象.
最后,在main范围的最后,剩余的对象(3,3,1)被破坏.
我不明白这种行为,并没有找到解释.
任何人都可以详细说明发生的事情的顺序吗?
特别:
为什么&A(3)在第二个对象之前构造第三个对象A(2)?这是否与它们的创建有关(第三个是通过引用,第二个是按值),或者f是定义了方式(第二个是按值,第三个是指针)?
当return *c;运行时,创建了第三个对象的副本归还.然后,在返回之前被破坏的唯一对象是第二个对象.同样,这与他们的创作有关,还是f定义了方式?
提前致谢.
为什么在第二个对象A(2)之前构造第三个对象&A(3)?这与它们的创建有关(第三个是通过引用,第二个是按值),或者是f定义的方式(第二个是值,第三个是指针)?
之所以发生这种情况,是因为C++标准没有指定函数参数的评估顺序.编译器可以根据需要对它们进行评估.这是许多未定义行为实例的原因,当不知道这种情况的程序员依赖于不存在的排序时.
当返回*c; 运行,创建第三个对象的副本以返回.然后,在返回之前被破坏的唯一对象是第二个对象.同样,这与他们的创作有关,还是与f的定义方式有关?
是的,是的.该A(2)物体是由函数参数的直接初始化创建f.函数参数的范围是函数体.因此A(2)功能退出的时刻就超出了范围.其他对象的生命周期稍长,因为它们是在函数外部创建的,并通过引用/指针传递.它们存在直到完整表达式结束f(1, A(2), &A(3));,因此它们将在以后被破坏.