我试图制作一个对象的副本,这是一个循环队列。我的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;
}
答案 0 :(得分: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
}
编辑:是的,你是对的,你仍然需要一个复制构造函数。
答案 1 :(得分:1)
将赋值运算符函数更改为并注意自我赋值
void CQUEUE::operator=(const CQUEUE& w)
{
if (this == &w)
return *this;
//Paste your code
}
答案 2 :(得分:1)
你有点落后。
通常,赋值运算符比复制构造函数更复杂,因为它需要在移动到新值之前正确处理所保留的资源。
通常更容易用简单的部件组成复杂的系统,而不是创建 do-it-all 部分并在其上表达简单的系统。在您的上下文中,这意味着从复制构造函数创建赋值运算符更容易。
因此,只需完全编写复制构造函数:
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;
}
这个成语被称为 copy-and-swap (是的,非常有创意!)。
注意:奖励说明,如果您有移动构造函数,那么它将成为免费的移动和交换。