(我的问题的答案涉及复制构造函数,但是复制发生在从函数返回时,而不是在对另一个类的方法调用中。我实际上看到了引用的可能重复项,但没有从 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;
}
我得到这个输出:
幻影 1 构建。 幻影 2 构建。 幻影2被毁。 幻影2被毁。 幻影 2 会说话。
这是输出中的第四行让我感到困惑。
Phantom 1 是在main
输入时自动构建的。
Phantom 2 是在getPhantom
输入时自动构建的。
Phantom 2 在getPhantom
退出时会自动销毁(这就是为什么我认为返回它getPhantom
是不安全的)。
但在那之后我很困惑。根据调试器,在第四行输出出现之前getPhantom
已经返回。第二次调用 's 的析构函数时,调用栈是这样的:Phantom
主要的 ~幻影
在托管语言中,我可以看到这一行:
phantom = getPhantom();
会破坏 Phantom 1,但不会触及 Phantom 2。这是 C++,而不是 Java。
是什么导致第二次调用 Phantom 2 的析构函数?