【问题标题】:Operator Overloading for Queue C++队列 C++ 的运算符重载
【发布时间】:2012-04-09 23:25:21
【问题描述】:

我试图使用重载运算符方法将一个队列的条目复制到另一个队列中,但我的函数出错了。我不知道如何以其他方式访问队列“原始”的值,而不是以下方式:

struct Node
{
   int item;
   Node* next;
};

class Queue
{
public:
    // Extra code here
    void operator = (const Queue &original);
protected:
    Node *front, *end;
};

void Queue::operator=(const Queue &original)
{
    //THIS IS WHERE IM GOING WRONG
    while(original.front->next != NULL) {
        front->item = original.front->item;
        front->next = new Node;
        front = front->next;
        original.front = original.front->next;
    }
}

【问题讨论】:

  • 已经有一个std::queue 类。

标签: c++ class queue operator-overloading


【解决方案1】:

你有一个功能复制构造函数吗?如果是这样,我会根据您的复制构造函数来实现您的赋值运算符,如下所示:

#include <algorithm>  // <utility> for C++11

void Queue::operator=(const Queue &other)
{
    // Assumes your only field is the "front" pointer.

    Queue tmp(other);   // May throw.
    std::swap(front, tmp.front);  // Will not throw.
}

这个想法是你在一个临时对象中执行任何可能引发异常的操作(比如你对operator new()的调用),该对象将清理资源,然后通过交换内容来“提交”你的更改一个非抛出操作,这样即使tmp 的构造过程中抛出异常,你的Queue 的状态也是正常的。指针分配保证不会抛出,这就是为什么在这种情况下对std::swap() 的调用不会抛出。离开赋值运算符tmp 的范围后,析构函数应该清理旧的链接列表,因为它的front 已与旧的front 交换。

有关此“copy-to-temporary-and-swap”习语的详细信息,以及它与强大的异常安全保证的关系,请参阅GotW #59

【讨论】:

    【解决方案2】:
    void Queue::operator=(const Queue &original)
    {
        Node* tmp = original.front;
        //THIS IS WHERE IM GOING WRONG
        while(tmp->next != NULL) {
            front->item = tmp->item;
            front->next = new Node;
            front = front->next;
            tmp = tmp->next;
        }
    }
    

    【讨论】:

    • 这不就是我正在做的吗?
    • 没有。你总是在你的版本中修改前端。在上面的版本中是在开始之前修改的,但不是在循环中所以前面没有改变并指向队列的开始。
    • 唷,我认为这个想法很简单——你修改的内容有所不同。在您的示例中,您正在更改引用中的对象,在我的示例中,您有自己的变量,您可以更改
    • 请注意,这是意料之外的,目标队列是扩展的,而不是分配的(operator= 会暗示)。
    猜你喜欢
    • 2011-09-21
    • 1970-01-01
    • 2018-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    相关资源
    最近更新 更多