我有以下代码:
class thing {
public:
thing(const thing& x) { cout << "copy" << endl; }
thing() { cout << "create" << endl; }
~thing() { cout << "destroy" << endl; }
thing& operator=(const int& rhs) { cout << "assign" << endl; }
};
int foo(thing x) {
return 5;
}
int main() {
thing bar;
thing newThing;
newThing = foo(bar);
getchar();
}
当我运行此程序时,在程序到达getchar()
时,我希望看到以下输出:
create // since bar is default constructed
create // since newThing is default constructed
copy // since bar gets passed by value into foo
destroy // since foo's local thing `x` is destructed when foo ends
assign // since the 5 returned by foo is assigned to newThing
相反,我明白了:
create
create
copy
assign
destroy
请注意,assign和destroy已经与我的预期交换了。
这是怎么回事?为什么在本地x
被破坏之前,分配似乎发生?请注意,如果我在foo的主体中声明了一个本地thing
,它会在赋值发生之前被破坏,正如我所期望的那样。
答案 0 :(得分:5)
有了这个签名:
int foo(thing x) {
return 5;
}
您正在创建一个thing
实例是参数的函数。参数由方法的调用者传入,表示此处的表达式:
newThing = foo(bar);
创建thing
的临时对象,该对象从bar
复制。那些临时代表的生命周期一直到完整表达式的结尾,因此在赋值发生后,这个临时函数的析构函数被称为。
为什么会这样?因为编译器只生成一个名为foo
的函数,并且此函数无法在本地构造x
,所以它不知道构造它的参数。可能存在多个可能有效的构造函数和几组不同的参数。因此编译器必须在呼叫的呼叫方一侧构建临时。
答案 1 :(得分:1)
参数由调用者构造和销毁,而不是由方法构造和销毁。 'foo()的本地事物'根本不是foo(),它是来电者:来电者摧毁它。