我有以下代码:
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();
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,在程序到达的位置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
Run Code Online (Sandbox Code Playgroud)
相反,我明白了:
create
create
copy
assign
destroy
Run Code Online (Sandbox Code Playgroud)
请注意,assign和destroy已经与我的预期交换了.
怎么了?为什么分配似乎在本地被破坏之前发生x?请注意,如果我thing在foo的主体中声明一个局部,它会在赋值发生之前被破坏,正如我所期望的那样.
有这个签名:
int foo(thing x) {
return 5;
}
Run Code Online (Sandbox Code Playgroud)
您正在创建一个函数,其中实例thing是一个参数.参数由方法的调用者传入,这意味着这里的表达式:
newThing = foo(bar);
Run Code Online (Sandbox Code Playgroud)
创建thing从中复制的临时对象bar.那些临时代表的生命周期一直到完整表达式的结尾,因此在赋值发生后调用此临时函数的析构函数.
为什么会这样?因为编译器只生成一个被调用的函数,foo并且该函数不能x在本地构造- 它不知道构造它的参数.可能存在多个可能有效的构造函数和几组不同的参数.因此,编译器必须在调用的调用者一侧构造临时.