【问题标题】:Overloading the + operator with a single-linked list用单链表重载 + 运算符
【发布时间】:2015-02-04 09:19:41
【问题描述】:

对于我的家庭作业,我必须创建一个 int 链接列表。我重载了复制构造函数和赋值运算符,但似乎使 + 运算符重载。我有一个已定义的析构函数来清除列表。

List List::operator+(const List &add)
{
     List result;
     result += *this;
     result += add;
     return result;
}

+= 正在工作。另外,当我执行以下操作时: 列表列表 3 = 列表 1 + 列表 2; 有用。似乎析构函数在它返回之前就被调用了,所以如果我这样做的话,我不会得到 List3 的任何东西

List list3;    
list3 = list1 + list2;

这里是复制构造函数、赋值重载和+=重载

List& List::operator=(const List &assign)
{
    Node *traverse = assign.head;
    int x;
    int *passX = &x;
    while (traverse != nullptr)
    {
        x = traverse->getItem();
        this->Insert(passX);
        traverse = traverse->getNext();
    }
    return *this;
}

List342& List342::operator+=(const List342 &add)
{
    Node *traverse = add.head;
    int x;
    int *passX = &x;
    while (traverse != nullptr)
    {
        x = traverse->getItem();
        this->Insert(passX);
        traverse = traverse->getNext();
    }
    return *this;
}

List342::List342(const List342 &copy)
{
    *this = copy;
}

struct Node
    {
        int item;
        Node *next = nullptr;
        int getItem() const;
        Node* getNext() const;
        void setItem(const int &val);
        void setNext(Node* nodePtr);
    };
    Node *head;
    int itemCount;

最后一部分是节点的结构体,以及这个类的任何对象都会有的两个变量。

谢谢

【问题讨论】:

  • 你服从the rule of three吗?实际复制列表还是只复制指针?
  • 重现问题的邮政编码...
  • + 看起来不错。如果复制构造有效,则问题出在赋值运算符上。
  • 至少显示operator=operator+=以及copy-constructor和类定义
  • 我们仍然需要一个 MCVE 来解决这个问题。见stackoverflow.com/help/mcve

标签: c++ linked-list operator-overloading


【解决方案1】:

所以我设法解决了这个问题

List& List::operator+(const List &add)
{
    List *result = new List;
    *result = *this;
    *result += add;
     return result;
}

我的析构函数在返回之前清除了列表...在堆中分配空间会阻止析构函数这样做。

感谢大家的帮助!

【讨论】:

  • 这是错误隐藏,而不是实际问题。我怀疑它在您没有显示的那些函数之一中,可能是 List::List() 或 List::Insert()
【解决方案2】:

很好地将 operator+ 实现为 operator+= 的函数。但是,在重载运算符 + 时,您应该同时声明 LHS 和 RHS const。

const List List::operator+(const List &add) const
{
     List result;
     result += *this;
     result += add;
     return result;
}

第一个const表示函数返回一个const List,所以不能:

List A, B, C;
A + B = C;

第二个表示函数没有修改它的成员变量,所以你可以相信A+B不会修改A。

假设默认构造函数是一个空列表并且您的类不使用指针,请尝试正确声明 const。 const 变量的作用域与非 const 不同。如果您的类使用指针,请确保您实际上是在复制相关内存,而不仅仅是内存地址。

【讨论】:

  • 不确定我是否理解为什么结果应该是 const。例如l3.Splice(l1+l2)
  • 返回 const 是个坏主意;除其他外,它可以防止移动。如果要阻止A + B = C;,正确的解决方案是对operator= 应用ref-qualifier
  • 结果应该是 const 因为A + B 不应该是 lhs 值。 l3.Splice(l1+l2)l3.Splice(l1+l2) 是否应该修改 l1l2?这是模棱两可的代码,而且风格通常很糟糕。如果要在函数调用中使用 rhs 值,请将它们声明为 const...
  • 如果是 const,那么 C = A + B; 必须从 operator+ 返回的临时值中进行不必要的复制,而不是执行移动分配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-23
  • 2019-04-02
  • 2012-06-09
  • 2023-03-23
  • 2010-12-06
  • 1970-01-01
相关资源
最近更新 更多