为什么会发生这种情况?operator=和拷贝构造函数

3

我有以下几个类:

class CRectangle
{
    CRectangle(string color);
    CRectangle(CRectangle &origin);
    /* Some more code */
};

and this other:

class CPlane
{
    /* Some more code */
    CRectangle boundingBox();
};

为什么我能做到这个?:
CRectangle rectangle1;
CRectangle rectangle2=rectangle1;
CRectangle rectangle3(rectangle1); //Copy constructor.

但我无法做到这一点:

CPlane plane;
CRectangle rectangle4=plane.boundingBox();
CRectangle rectangle5(plane.boundingBox()); //Copy constructor.

如果我需要让最后一个工作,该怎么办?我认为这可能与运算符=有关,但我不确定。

编辑:修复复制构造函数。错误仍然存在。


2
你的复制构造函数导致无限递归(复制导致复制,进而导致更多的复制……) - juanchopanza
对于复制构造函数,应该将参数作为const引用传递。 - Cornstalks
1
作为未来的提示,当某些东西“不工作”时,请包括确切地不工作的内容,例如编译器/运行时错误的文本或实际输出与期望输出的差异。 - aruisdante
2个回答

5

您的复制构造函数请求的第一种语法会导致编译器无限递归。

应该是:

CRectangle(const CRectangle& origin);

其次,这两个调用应该正常工作,因为它们都是复制构造函数的调用。

CRectangle rectangle4=plane.boundingBox();
CRectangle rectangle5(plane.boundingBox()); 

关于“请求编译器进行无限递归”的问题,是的,但首先它会向编译器请求一个错误诊断,因为该声明是无效的。我怀疑这个帖子的作者没有发布真正的代码。否则,他或她可能正在使用一些非常老旧或奇怪的编译器。 - Cheers and hth. - Alf
@Cheersandhth.-Alf 我正在使用Eclipse Luna,使用真实的代码。我通过以下方式使其工作:CRectangle box("azul"); box=plano.boundingBox("",""); 但我想尝试第二种方法,但它不允许我这样做。 - IzonFreak
@IzonFreak:Eclipse是一个集成开发环境,而不是编译器。通常情况下,使用Eclipse时会用到g++或clang。如果该声明可以编译通过,那么它很可能是某个非常旧的版本。 - Cheers and hth. - Alf

3
您不能将rvalue绑定到非const lvalue引用。
CRectangle rectangle3(rectangle1);

这里的rectangle1是一个非const左值,所以没问题。

CRectangle rectangle5(plane.boundingBox());

plane.boundingBox() 是纯右值(prvalue),因此 CRectangle& 无法绑定到它。

相反,声明您的复制构造函数以使用 const 引用:

CRectangle(CRectangle const&);

或者,如果需要的话,还可以声明移动构造函数。


我刚刚检查了我的代码,确实有CRectangle(CRectangle&origin);只是在发布时出现了错误。 - IzonFreak
@IzonFreak... 你不是认真的吧。 - Columbo
是的,我忘记在这篇文章中加上&符号,但是在我的代码中它是存在的,问题仍然存在,我无法创建CRectangle rectangle5(plane.boundingBox())。 - IzonFreak
@IzonFreak 修改了我的答案。 - Columbo
1
@IzonFreak 什么?你无法复制/粘贴吗? - Martin James
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接