我试图理解C ++标准关于从函数返回对象时应如何/何时调用析构函数的说法-考虑这个简单的结构和两个功能-
#include <iostream>
int g = 0;
struct foo {
int myid;
foo() {
myid = g;
g++;
std::cout << "Created " << myid << std::endl;
}
~foo() {
std::cout << "Destroyed " << myid << std::endl;
}
};
foo bar(void) {
int i = 0;
for (foo s; i < 10; i++) {
if (i == 5)
return s;
}
}
foo bar2(void) {
int i = 0;
foo s;
for (; i < 10; i++) {
if (i == 5)
return s;
}
}
int main() {
bar();
bar2();
return 0;
}
我正在尝试跟踪析构函数的调用次数。上面程序的输出是-
Created 0
Destroyed 0
Destroyed 0
Created 1
Destroyed 1
我可以理解bar2
的行为。对象创建一次并销毁(我相信析构函数是从main调用的)。但是在bar
中,在循环内声明对象时。它将析构函数调用两次。这种差异的原因是什么?
是不是这种情况将这种行为留给实现(由于复制省略?),而g ++在这两种情况下都选择了这种行为?如果是这样,我该如何编写此函数,以便获得可预测的行为。我需要将析构函数的调用次数与构造函数的调用次数完全相同(最好以相反的顺序)。我同意,只要构造函数也被调用两次,析构函数就会被调用两次。原因是因为我在构造函数内部分配了一些数据,并在析构函数内部释放了数据。
添加此代码
foo(const foo& rhs) {
myid = g;
g++;
std::cout << "Created from copy " << myid << std::endl;
}
这是一个复制构造函数,也只是在您不知道的情况下才被调用,因为您使用的是默认版本,该版本显然不打印任何内容,也不增加计数器。