【发布时间】:2012-04-10 22:31:19
【问题描述】:
我有以下简单的代码,其中包含一个普通构造函数和一个复制构造函数
class largeObj
{
public:
largeObj()
{
printf("\nNormal constructor\n");
}
largeObj(const largeObj& mv)
{
printf("\nCopy constructor\n");
}
~largeObj()
{
printf("\nDestroying..\n");
}
void tryme()
{
printf("\nHi :)\n");
}
};
largeObj iReturnLargeObjects()
{
largeObj md;
return md;
}
int main()
{
largeObj mdd = iReturnLargeObjects();
mdd.tryme();
return 0;
}
输出是
普通构造函数
复制构造函数
破坏..
嗨 :)
我明白了。
但如果我替换以下行
largeObj mdd = iReturnLargeObjects();
与
largeObj& mdd = iReturnLargeObjects();
输出都是一样的,这是为什么呢?
我的意思是:在第一种情况下不应该有另一个副本(没有 &)吗?这两条线有什么区别,为什么它们的行为相同?
【问题讨论】:
-
第二个甚至不应该编译。它将临时绑定到对非常量的引用。
-
我做了一些调试,发现iReturnLargeObjects()中的md对象调用了普通的构造函数,然后在return md时调用了复制构造函数;然后在从 iReturnLargeObjects() 返回之前对 md 对象调用析构函数。所以大概在内存中创建了另一个 largeObj。问题是:为什么 largeObj mdd = object 不创建另一个复制变量?这是因为 RVO 吗?所以这里的每个人都同意第二个 largeObj& mdd = 对象是完全非法的,并且由于一些奇怪的东西而编译
-
@jrok,它应该仍然可以编译。例如,如果您在堆栈上创建引用,则该引用不会被视为临时引用,因为编译器不会检查它的来源,只会检查它的有效引用,因此当它被返回时,它返回为一个参考。这仅是因为它是复制构造函数。