(我的问题的答案涉及复制构造函数,但复制发生在从函数返回时,而不是在对另一个类的方法调用中。我实际上看到了引用的可能重复项,但没有从vector::push_back 我的函数在这里也做了一个拷贝。也许我应该有。)
我想了解自动对象的构造/破坏。我遇到了一些对我来说可疑的代码,所以我编写了自己的版本以努力理解它。简而言之,原始代码包含一个返回函数本地对象(自动对象)的函数。这对我来说看起来不安全,所以我编写了这个程序来探索它:
#include <stdio.h>
class Phantom
{
private:
static int counter;
int id;
public:
Phantom()
{
++counter;
id = counter;
printf("Phantom %d constructed.\n", id);
};
virtual ~Phantom()
{
printf("Phantom %d destructed.\n", id);
};
void speak()
{
printf("Phantom %d speaks.\n", id);
};
};
int Phantom::counter = 0;
Phantom getPhantom()
{
Phantom autoPhantom;
return autoPhantom; // THIS CAN'T BE SAFE
}
int main()
{
Phantom phantom;
phantom = getPhantom();
phantom.speak();
return 0;
}
我得到这个输出:
Phantom 1 constructed. Phantom 2 constructed. Phantom 2 destructed. Phantom 2 destructed. Phantom 2 speaks.
It's the fourth line in the output that confuses me.
Phantom 1 is constructed automatically when main
is entered.
Phantom 2 is constructed automatically when getPhantom
is entered.
Phantom 2 is destructed automatically when getPhantom
is exited (which is why I believe returning it from getPhantom
is unsafe).
But after that I'm confused. According to the debugger, getPhantom
has returned before the fourth line of output appears. When Phantom
's destructor is called the second time, the call stack is this:
main ~Phantom
In a managed language, I could see how this line:
phantom = getPhantom();
会破坏 Phantom 1,但不会影响 Phantom 2。这是 C++,不是 Java。
是什么导致第二次调用 Phantom 2 的析构函数?
最佳答案
您返回一份拷贝。因此 getPhantom()
中的变量在作用域的末尾被销毁,你留下它的拷贝也有 id 2。这是因为在返回时它调用复制构造函数(也是默认的)不会增加 id。
关于c++ - 为什么自动对象的析构函数被调用两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38481573/