0

我试图制作一个对象的副本,这是一个循环队列。我的 Enqueue 和 Dequeue 工作正常,但每当我这样做时,都会出现运行时错误。

CQUEUE j = k;

输出窗口说我的复制构造函数在所有控制路径上都是递归的?有人可以帮我弄清楚我做错了什么吗?这是我的复制构造函数,以及重载的赋值运算符。

CQUEUE::CQUEUE(const CQUEUE& original)
{
(*this) = original;
}


void CQUEUE::operator=(CQUEUE w)
{
qnode *p = w.front;
(*this).front = new qnode;
(*this).back = front;

while(p -> next != w.back)
{
  back -> num = p -> num;
  p = p -> next;
  back -> next = new qnode;
  back = back -> next;
}

back -> num = p -> num;
p = p -> next;
back -> next = new qnode;
back = back -> next;
back -> num = p -> num;

back -> next = front;
front -> prev = back;
}
4

3 回答 3

4
(*this) = original;

编译器使这一行调用复制构造函数而不是您的 = 运算符,因为您的 = 运算符当前采用非常量的按值CQUEUE。相反,您的 = 运算符应如下所示:

void CQUEUE::operator=(const CQUEUE& w)

然后你的复制构造函数将调用你的 operator = 。或者,使其更明确:

CQUEUE::CQUEUE(const CQUEUE& original)
{
    Copy(original);
}

void CQUEUE::operator=(const CQUEUE& w)
{
    Copy(w);
}

void CQUEUE::Copy(const CQUEUE& other)
{
    // All your copy code here
}

编辑:是的,你是对的,你仍然需要一个复制构造函数。

于 2012-07-10T05:42:56.080 回答
1

将赋值运算符函数更改为并注意自赋值

void CQUEUE::operator=(const CQUEUE& w)
{
   if (this == &w)
        return *this;

   //Paste your code
}
于 2012-07-10T05:39:47.537 回答
1

你做的有点倒退。

一般来说,赋值运算符比复制构造函数更复杂,因为它需要在移动到新值的基础上正确处理持有的资源。

用简单的部分组成一个复杂的系统通常比创建一个全能的部分并在其上表达简单的系统更容易。在您的上下文中,这意味着从复制构造函数创建赋值运算符更容易。

因此,只需完整地编写复制构造函数:

CQUEUE(CQUEUE const& c) { ... }

然后编写一个例程来交换(交换内容)两个CQUEUE实例:

void swap(CQUEUE& c) {
    using std::swap;
    swap(front, c.front);
    swap(back, c.back);
}

最后,用它们构建赋值运算符:

CQUEUE& operator=(CQUEUE c) { // copy
    this->swap(c);
    return *this;
}

这个成语被称为复制和交换(是的,非常有创意!)。

Note: bonus note, if you have a move constructor, then it becomes a move-and-swap for free.

于 2012-07-10T06:44:39.227 回答