C++ 单链表中的重载赋值运算符
我正在学习链表。我创建了一个模板实现,包括一个构造函数、一个插入器、一个析构函数、一个复制构造函数和一个重载赋值运算符。问题是,我的测试程序在重载赋值运算符后不会输出任何内容 对于赋值运算符,我使用C++ 单链表中的重载赋值运算符,c++,linked-list,operator-overloading,assignment-operator,C++,Linked List,Operator Overloading,Assignment Operator,我正在学习链表。我创建了一个模板实现,包括一个构造函数、一个插入器、一个析构函数、一个复制构造函数和一个重载赋值运算符。问题是,我的测试程序在重载赋值运算符后不会输出任何内容 对于赋值运算符,我使用Clear()函数在复制之前完全清除列表。我把它放在析构函数里,检查它是否正常工作。我还检查了我的复制构造函数,它也工作得很好 文件node.h:定义节点构建块 #include <iostream> using namespace std; template <typename
Clear()
函数在复制之前完全清除列表。我把它放在析构函数里,检查它是否正常工作。我还检查了我的复制构造函数,它也工作得很好
文件node.h
:定义节点构建块
#include <iostream>
using namespace std;
template <typename T>
struct Node{
T _item;
Node<T>* _next;
Node() {
_item = T();
_next = NULL;
}
Node(T item){
_item = item;
_next = NULL;
}
// Print the value of a node
friend std::ostream& operator <<(std::ostream& outs, const Node<T> &printMe){
outs << "[" << printMe._item << "]";
return outs;
}
};
此标题还提供这些成员函数的实现:
template <class T>
List<T>::List(){
head = NULL;
}
template <class T>
List<T>::~List(){
Clear();
}
template <class T>
List<T>::List(const List<T> ©This){
if (copyThis.head == NULL)
head = NULL;
else {
// Create walker for the original linked list
Node<T>* walker = copyThis.head->_next;
// Create new head node for new linked list
head = new Node<T>(copyThis.head->_item);
// Create new walker for new linked list
Node<T>* new_walker = head;
// Iterate walker and new walker and copy each item in the original list to new linked list
while (walker!= NULL) {
new_walker->_next = new Node<T>(walker->_item);
walker = walker->_next;
new_walker = new_walker->_next;
}
}
}
template <class T>
List<T>& List<T>::operator =(const List<T>& RHS){ // DOESN'T WORK
if (this != &RHS) {
this->Clear();
*this = List<T>(RHS);
}
return *this;
}
template <class T>
Node<T>* List<T>::InsertHead(T i){
Node<T>* temp = new Node<T>(i);
temp->_next = head;
head = temp;
return head;
}
// Clear a linked list
template <class T>
void List<T>::Clear(){
Node<T>* current = head;
Node<T>* next = new Node<T>;
while (current != NULL) {
next = current->_next;
delete current;
current = next;
}
head = NULL;
}
template <class U>
ostream& operator <<(ostream& outs, const List<U>& l){
Node<U>* walker = l.head;
while(walker != NULL){
outs << *walker;
outs << "->";
walker = walker->_next;
}
outs << "|||";
return outs;
}
我目前的问题是重载赋值运算符函数。下面是我从copy构造函数复制整个执行并运行它的时候
template <class T>
List<T>& List<T>::operator =(const List<T>& RHS){
if (this != &RHS) {
this->Clear();
if (copyThis.head == NULL)
head = NULL;
else {
// Create walker for the original linked list
Node<T>* walker = copyThis.head->_next;
// Create new head node for new linked list
head = new Node<T>(copyThis.head->_item);
// Create new walker for new linked list
Node<T>* new_walker = head;
// Iterate walker and new walker and copy each item in the original list to new linked list
while (walker!= NULL) {
new_walker->_next = new Node<T>(walker->_item);
walker = walker->_next;
new_walker = new_walker->_next;
}
}
return *this;
}
但是,当我像下面这样简化代码时,它不会输出任何内容:
template <class T>
List<T>& List<T>::operator =(const List<T>& RHS){
if (this != &RHS) {
this->Clear();
*this = List<T>(RHS);
}
return *this;
}
模板
列表和列表::运算符=(常量列表和RHS){
如果(此!=&RHS){
这个->清除();
*此=列表(RHS);
}
归还*这个;
}
有人能告诉我为什么它不起作用,以及如何有效地简化它吗?我真的很感激。这个问题
由于堆栈溢出,赋值运算符停止所有操作
事实上,赋值运算符的实现本身使用赋值运算符,因此它递归调用自身,直到堆栈耗尽:
*this = List<T>(RHS); // OUCH !!
| | |
V V V
<ListT> operator= List<T> ==> cals operator= again !!
*此=列表(RHS);//哎哟
| | |
V V V
操作员=列表==>cals操作员=再次!!
解决方案
附加提示:为操作员过载推荐一些良好而优雅的做法。对于赋值运算符,它建议使用复制构造函数(正如您尝试做的那样),但不是赋值(您的问题),而是交换(有待验证,但在您的情况下交换头肯定会奏效) 当您调用
*时,此=列表(RHS)代码>你希望运行什么代码?@Tim Randall:在我清除当前对象后,我想将整个内容从RHS复制到当前对象。或者你可以只使用std::list
或std::forward\u list
或(通常更好)std::vector
@Jesper Juhl:我不允许在代码中使用它。我还想了解为什么我不能使用*this=List(RHS);我想它会从RHS复制整个内容,因为我有上面的复制构造函数,我想将整个内容从RHS复制到当前对象。这正是赋值操作符所做的。你说的是“我的赋值运算符做我的赋值运算符做的”。这对我来说有点像圆形。@BrandonWilliams不客气。我用一个有趣的建议进行了编辑。
2->3->|||
template <class T>
List<T>& List<T>::operator =(const List<T>& RHS){
if (this != &RHS) {
this->Clear();
*this = List<T>(RHS);
}
return *this;
}
*this = List<T>(RHS); // OUCH !!
| | |
V V V
<ListT> operator= List<T> ==> cals operator= again !!