重载用于添加两个双链表的运算符
Overloading operators for adding two doubly linked lists
我需要帮助重载'+'运算符,以便将两个双链表添加在一起。由于出现"运算符=…不匹配"错误,我无法编译程序。我已经重载了"="运算符,但很难将添加的结果打印到std输出中。我还使<lt;操作人员几个小时以来,我一直试图找出问题所在,但没有成功。任何关于如何解决这个问题和/或解决方案的提示都是非常受欢迎的。这是我OOP课的作业。提前感谢!
编辑:代码背后的基本思想是复制集合。重载运算符"+"应作为并集,"*"应作为交集。我很难将并集正确打印到std输出。'+='看来效果不错<lt;'效果也很好,但只有在打印单个列表时。
编辑:编译器产生的错误(g++,从代码输出::块,我删除了编译器注释):
llist3.cpp|149|error: no match for ‘operator=’ (operand types are ‘LList’ and ‘LList’)|
llist3.cpp|106|note: no known conversion for argument 1 from ‘LList’ to ‘LList&’|
llist3.cpp|151|error: no match for ‘operator=’ (operand types are ‘LList’ and ‘LList’)|
llist3.cpp|106|note: no known conversion for argument 1 from ‘LList’ to ‘LList&’|
llist3.cpp|152|error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘LList’)|
#include<iostream>
using namespace std;
class LList {
public:
struct Node {
int elem;
Node* succ;
Node* prev;
Node() : succ(0), prev(0), elem(0) {}
};
LList();
LList(LList& list);
~LList();
Node* next();
Node* begin() { curr = head; }
int getElem() { return curr->elem; }
void addElem(int elem);
LList operator+(LList& set);
LList operator+(int elem);
LList& operator+=(LList& set);
LList& operator+=(int elem);
LList& operator=(LList& list);
friend ostream& operator<<(ostream& os, LList& obj);
private:
Node* curr;
Node* head;
Node* tail;
int size;
void pushFront(Node* n);
void pushInside(Node* n);
void pushBack(Node* n);
};
LList::LList() : head(0), tail(0), size(0), curr(0) {}
LList::LList(LList& list) : size(0), curr(0), head(0), tail(0) {
list.curr = list.head;
while(list.curr) {
addElem(list.getElem());
list.next();
}
}
LList::Node* LList::next() {
if (curr)
return (curr = curr->succ);
else
return 0;
}
void LList::addElem(int elem) {
Node* n = new Node;
n->elem = elem;
if (curr) {
if (curr == head && elem < curr->elem) {
pushFront(n);
}
else if (elem > curr->elem) {
curr = curr->succ;
addElem(elem);
}
else if (elem < curr->elem && elem > (curr->prev)->elem) {
pushInside(n);
}
else if (elem < curr->elem) {
curr = curr->prev;
addElem(elem);
}
} else {
pushBack(n);
}
}
void LList::pushFront(Node* n) {
head = n;
n->succ = curr;
curr->prev = n;
n->prev = 0;
curr = n;
size++;
}
void LList::pushInside(Node* n) {
(curr->prev)->succ = n;
n->succ = curr;
n->prev = curr->prev;
curr->prev = n;
size++;
}
void LList::pushBack(Node* n) {
if (!head) {
head = n;
} else {
tail->succ = n;
n->prev = tail;
}
tail = n;
curr = n;
size++;
}
LList::~LList() {
for (curr = head; curr;) {
Node* temp = curr->succ;
delete curr;
curr = temp;
}
}
LList& LList::operator=(LList& list) {
list.begin();
if (this != &list) {
for (curr = head; curr;) {
Node* temp = curr->succ;
delete curr;
curr = temp;
}
while (list.curr) {
addElem(list.getElem());
list.next();
}
}
return *this;
}
ostream& operator<<(ostream& os, LList& list) {
LList::Node* p = list.head;
os << "{ ";
while(p) {
os << p->elem << (p->succ ? ", " : "");
p = p->succ;
}
os << " }" << endl;
return os;
}
LList LList::operator+(LList& set) {
LList temp = *this;
temp += set;
return temp;
}
LList LList::operator+(int elem) {
*this += elem;
return *this;
}
int main() {
LList setA;
setA.addElem(1234);
setA.addElem(1435);
setA.addElem(1100);
LList setB;
setB.addElem(1234);
setB.addElem(1435);
setB.addElem(5100);
setB = setA + 1234; // 1st error here
LList setD;
setD = setA + setB; //2nd
cout << setA + setB << endl; //3rd
}
您的代码中有一个明显的错误:
Node* begin() { curr = head; }
此代码调用未定义的行为,因为您没有返回值。应该是这样的:
Node* begin() { curr = head; return curr; }
此外,您应该在不更改LList
参数的函数中通过const引用传递LList
:
例如:
LList::LList(LList& list);
LList& operator=(LList& list);
friend ostream& operator<<(ostream& os, LList& obj);
应该是:
LList::LList(const LList& list);
LList& operator=(const LList& list);
friend ostream& operator<<(ostream& os, const LList& obj);
请更改这些函数和其他函数以传递常量引用。如果你想知道为什么你应该改变这一点,如果你试图这样做,你会立即看到问题:
LList list1;
LList list2;
//...
std::cout << list1 + list2;
operator <<
正在寻找非常量的LList
对象,但添加的"inline"返回一个临时LList
(这意味着返回值将是const
)。由于重载的operator <<
只接受非常数LList
,因此代码将不会编译。
因此,您需要将operator <<
中的参数更改为const LList&
。
您的列表类中有一个内置的"current"指针。这是一个严重的设计错误。由于此错误,您无法正确定义函数。
这是一个设计错误,因为使用此设计,您无法对const
列表进行迭代,这意味着,除了其他不好的事情外,您无法使用临时列表做任何有用的事情。因此,当你计算setA + setB
时,你不能把它分配给任何东西,因为要分配,你需要迭代,所以你需要给operator=
和复制构造函数一个非常量参数。但是,不能将临时引用绑定到非常量引用。
即使绕过复制构造函数和复制赋值运算符中的公共接口,在不使用curr
的情况下直接复制列表,任何必须使用公共接口的用户函数也会遇到同样的问题。也就是说,setA + setB
将不能用作函数参数。您需要先将其分配给某个变量,然后将该变量传递给函数。
您也不能在迭代过程中获取列表并将其传递给某个函数,并期望从您留下的位置继续迭代,因为任何迭代列表的操作都会更改curr
指针。
最好的解决方案是去掉curr
成员,并使您的大部分论点成为const LList&
。虽然这不是onky解决方案,但将当前指针构建到列表类中还有许多其他缺点,所以我不讨论它们。
为了迭代列表,您必须提供一个可以在列表上来回移动的单独对象,以及一个可在const列表上来回旋转的单独变体。这被称为迭代器,如果你想在C++中做任何事情,你需要了解这个概念。
在您的情况下,迭代器可以是Node*
和const Node*
。您只需要提供返回列表中第一个节点的成员函数,该节点已经存在。真正的图书馆也是如此。由于各种原因,它们通常将节点指针封装在一个单独的迭代器类中;但对于一个简单的家庭作业来说,这是不必要的(尽管如果你愿意,你可以做)。
- 如何在 c++ 中比较 2 个链表并将匹配的数据放入另一个链表中
- 创建一个棋盘格或"Interweave"两个链接列表。IE 更改两个链表的指针
- 重载 == 以递归方式比较两个链表
- 为什么我在尝试添加两个链表时出现此错误?
- 将 2 个链表中包含的相同值写入另一个链表
- 使用多重性函数与 in C++ 联合两个链表
- 如何将 2 个链表合并或合并在一起以创建新列表
- 如何使用超载 运算符组合两个链接列表
- 深度使用两个链接列表的邻接列表的首次搜索C 实现
- 随机合并两个链表
- 我如何合并C 中的两个链接列表
- 合并两个链表产生 seg 错误等
- 合并两个链表,没有重复
- C++我的第一个链表我做错了什么
- 两个链表的并集
- 查找两个链表的交集节点
- 检查两个单链表是否包含相同的数据
- 通过递归 - c++ 将排序的两个链表合并到第三个链表中
- c++合并两个链表分段错误和核心转储错误
- 两个链表的联合 - C++