使用下面的程序,我尝试使用copy ctor进行实验,有一点不清楚,当函数f( )
返回时,应该使用copy-ctor为{{1创建一个新对象但是我想这是由临时对象完成的,它使用对象的构造函数,然后制作副本,但是破坏输出显示我在这个推理上错了...在这个问题上有一些澄清;)< / p>
h2
输出
#include <fstream>
#include <string>
using namespace std;
ofstream out("HowMany2.out");
class HowMany2 {
string name; // Object identifier
static int objectCount;
public:
HowMany2(const string& id = "") : name(id) {
++objectCount;
print("HowMany2()");
}
~HowMany2() {
--objectCount;
print("~HowMany2()");
}
// The copy-constructor:
HowMany2(const HowMany2& h) : name(h.name) {
name += " copy";
++objectCount;
print("HowMany2(const HowMany2&)");
}
void print(const string& msg = "") const {
if(msg.size() != 0)
out << msg << endl;
out << '\t' << name << ": "
<< "objectCount = "
<< objectCount << endl;
}
};
int HowMany2::objectCount = 0;
// Pass and return BY VALUE:
HowMany2 f(HowMany2 x) {
x.print("x argument inside f()");
out << "Returning from f()" << endl;
return x;
}
int main() {
HowMany2 h("h");
out << "Entering f()" << endl;
HowMany2 h2 = f(h);
}
答案 0 :(得分:2)
h copy copy
基本上是h2
来自此行:
HowMany2 h2 = f(h);
退出main
时会被破坏。
h copy
是f
的参数,它在f
返回时被破坏。由于f
在main
之前返回,h copy
会在h copy copy
之前被删除。
请注意,RVO(返回值优化)由编译器完成。此代码中没有创建临时值。实际上,根据编译器,此代码可能会输出不同的结果。编译器可以在此代码中自由地对复制构造函数进行1或2次调用。 (在这种情况下也许可能为零,但我不知道如何证明它。)
编辑:您的代码由编译器实现(伪代码):
void f(HowMany2 *result, HowMany2* xptr) {
HowMany2 x(*xptr); // local copy
x.print("x argument inside f()");
out << "Returning from f()" << endl;
new(result) HowMany2(x); // copy the return value
x.~HowMany(); // destroy local copy
}
int main() {
HowMany2 h("h");
out << "Entering f()" << endl;
HowMany2 h2; // not initialized
f(&h2, &h);
h2.~HowMany2();
}
答案 1 :(得分:1)
在那个“混淆”点,函数f的临时本地对象被销毁(“h copy”),之后它被返回以在函数外创建副本(“h copy copy”)。然后,函数外部的对象按其创建的相反顺序销毁:复制的对象(“h copy copy”),最后是原始对象(“h”)。
答案 2 :(得分:0)
f()的返回值是将复制结构复制回main
结果将值放入变量h2
。
因此,函数中的参数x
首先被销毁(因为它离开了函数)
然后h2
然后h
作为主函数退出并且其局部变量被销毁。
~HowMany2()
h copy: objectCount = 2 // destruction of x
~HowMany2()
h copy copy: objectCount = 1 // destruction of h2
~HowMany2()
h: objectCount = 0 // festruction of h
如果你想真的吓坏了。在GCC上将优化转换为完全-O3或在VisStudio中以版本模式生成。看看输出有何不同。