我有以下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)被破坏。
我不明白这种行为,并没有找到解释。
任何人都可以详细说明发生的事情的顺序吗?
具体做法是:
为什么在第二个对象main
之前构造第三个对象&A(3)
?这与它们的创建有关(第三个是引用,第二个是值),或者A(2)
的定义方式(第二个是值,第三个是指针)?
运行f
时,会创建第三个对象的副本以便返回。
然后,在返回之前被破坏的唯一对象是第二个对象。同样,这与他们的创作有关,还是与定义return *c;
的方式有关?
提前致谢。
答案 0 :(得分:6)
为什么在第二个对象A(2)之前构造第三个对象&amp; A(3)?这与它们的创建有关(第三个是引用,第二个是值),或者f的定义方式(第二个是值,第三个是指针)?
这是因为函数参数的评估顺序未被C ++标准指定。编译器可以根据需要对它们进行评估。这是许多未定义行为实例的原因,当没有意识到这一点的程序员依赖于不存在的排序时。
返回时* c;运行,创建第三个对象的副本以返回。然后,在返回之前被破坏的唯一对象是第二个对象。同样,这与他们的创作有关,还是与f的定义方式有关?
有点,是的。 selected
对象是通过直接初始化函数selected="false"
的参数创建的。函数参数的范围是函数体。因此A(2)
在函数退出时就超出了范围。其他对象的生命周期稍长,因为它们是在函数外部创建的,并通过引用/指针传递。它们存在直到完整表达式f
结束,因此它们将在以后被破坏。