2

我有以下代码:

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

请注意,分配和销毁已与我的预期交换。

这是怎么回事?为什么分配似乎发生本地x被破坏之前?请注意,如果我thing在 foo 的主体中声明一个 local,它会在分配发生之前被破坏,正如我所期望的那样。

4

2 回答 2

5

有了这个签名:

int foo(thing x) {
    return 5;
}

您正在创建一个函数,其中的实例thing是一个参数。参数由方法的调用者传入,这意味着这里的表达式:

newThing = foo(bar);

创建一个thing从中复制的临时对象bar。这些临时对象的生命周期直到完整表达式结束,因此在分配发生后调用此临时对象的析构函数。

为什么呢?因为编译器只生成一个被调用的函数foo,而这个函数不能x在本地构造——它不知道用哪些参数来构造它。可能有多个有效的构造函数和几组不同的参数。因此,编译器必须在调用方的调用方构造临时。

于 2013-10-22T19:43:48.880 回答
1

参数由调用者构造和销毁,而不是由方法。'foo()'s local thing' 根本不是 foo() 的,它是调用者的:调用者破坏了它。

于 2013-10-22T19:44:20.080 回答