链表C ++中的赋值运算符 [英] Assignment operator in linked list C++
问题描述
我正在尝试用c ++实现链接列表。
I'm trying to implement linked list in c++.
我这样实现我的赋值运算符:
I implement my assignment operator like this:
// assignment operator
template<class T>
LinkedList<T>& LinkedList<T>::operator = (const LinkedList& rhs) {
if (&rhs != this) {
Node *tmp = head;
while (tmp -> next) {
head = head -> next;
delete tmp;
tmp = head;
}
tmp = rhs -> head;
while (tmp) {
append(tmp);
tmp = tmp -> next;
}
}
return *this;
}
在我的主要功能中,我使用以下代码进行测试:
In my main function, i use the following code to test:
LinkedList<int> *lst1 = new LinkedList<int>(7);
LinkedList<int> *lst2 = new LinkedList<int>(101);
std::cout << lst1 -> head -> data << std::endl;
std::cout << lst2 -> head -> data << std::endl;
lst1 = lst2;
std::cout << lst1 -> head -> data << std::endl;
delete lst1;
delete lst2; <--------------- error here
期望,控制台输出:
7 101101
7 101 101
但是当程序尝试删除lst2时,我得到一条错误消息:
But when the program try to delete lst2, i get an error saying:
释放的指针未分配
pointer being freed was not allocated
我使用调试器,找出程序何时进行赋值:
I use debugger and find out when the program is doing assignment:
lst1 = lst2;
lst1实际上是指指向lst2的地址,而不是获取lst2的副本,所以当我删除lst1,lst2已经消失。
lst1 is actually referring to the address that points lst2 instead of getting a copy of lst2, so when i delete lst1, lst2 is already gone.
那么有人可以告诉我我的赋值运算符怎么了吗?
很抱歉,如果这是一个新手问题,但我已经花了几个小时而无法弄清。
I'm sorry if this is a novice question but I've been spending a few hours and could not figure out.
我完成的代码如下所示:
My completed code is shown below:
template<class T>
class LinkedList {
private:
class Node {
public:
T data;
Node *next;
// default constructor
Node() = default;
// constructor with data
Node(const T& data) : data(data), next(NULL) {}
};
public:
Node *head;
LinkedList(const LinkedList& copyLst);
LinkedList& operator=(const LinkedList& byValList);
LinkedList() : head(NULL){}
LinkedList(Node *newNode) : head(newNode) {}
LinkedList(T val) {
head = new Node(val);
}
~LinkedList();
static LinkedList<int> sumLists(const LinkedList<int>& lst1, const LinkedList<int>& lst2) ;
void insertAtFront(T val);
void insertAtEnd(T val);
void printList();
void insert(T val);
void append(const Node&);
};
// copy constructor
template<class T>
LinkedList<T>::LinkedList(const LinkedList<T>& copyLst) {
const Node *cpCurrent = copyLst.head;
Node *lsCurrent = NULL;
if (cpCurrent != NULL) {
head = new Node(cpCurrent -> data);
lsCurrent = head;
cpCurrent = cpCurrent -> next;
}
while (cpCurrent != NULL) {
Node *newNode = new Node(cpCurrent -> data);
lsCurrent -> next = newNode;
lsCurrent = lsCurrent -> next;
cpCurrent = cpCurrent -> next;
}
}
// assignment operator
template<class T>
LinkedList<T>& LinkedList<T>::operator = (const LinkedList& rhs) {
if (&rhs != this) {
Node *tmp = head;
while (tmp -> next) {
head = head -> next;
delete tmp;
tmp = head;
}
tmp = rhs -> head;
while (tmp) {
append(tmp);
tmp = tmp -> next;
}
}
return *this;
}
// destructor
template<class T>
LinkedList<T>::~LinkedList() {
Node *current = head;
while (current != NULL) {
head = head -> next;
delete current;
current = head;
}
}
template<typename T>
void LinkedList<T>::append(const Node& node ){
if (NULL == head) {
Node *newNode = new Node(node -> data);
head = newNode;
} else {
Node *current = head;
while (current -> next) {
current = current -> next;
}
Node *newNode = new Node(node -> data);
current -> next = newNode;
}
}
推荐答案
您的当前实现会复制复制构造函数中已经存在的代码,所以为什么不重用它呢?
Your current implementation duplicates code that already exists in the copy constructor, so why not reuse it?
如果您有一个有效的复制构造函数和析构函数,请使用复制/交换惯用法是实现赋值运算符的最简单,最安全的方法。
If you have a working copy constructor and destructor, usage of the copy / swap idiom would be the easiest and safest way to implement the assignment operator.
#include <algorithm>
//...
template<class T>
LinkedList<T>& LinkedList<T>::operator = (const LinkedList<T>& rhs)
{
LinkedList<T> temp(rhs);
std::swap(temp.head, head);
return *this;
}
鉴于您的复制构造函数和析构函数可以正常工作,因此可以保证正常工作。我们创建对象 rhs
的副本 temp
并将其内容替换为的内容* this
。当 temp
在返回时被销毁时,它会同时包含以前在 * this
中的旧数据。
Given that your copy constructor and destructor work correctly, this is guaranteed to work correctly. We create a copy temp
of the object rhs
and swap out its contents with the contents of *this
. When temp
gets destroyed at the return, it takes along with it the old data that used to be in *this
.
如果您使用的是C ++ 11编译器,则可以利用带有传递值的传入参数进行移动构造。
If you have a C++ 11 compiler, you can take advantage of move construction on the passed-in parameter with pass-by-value.
#include <algorithm>
//...
template<class T>
LinkedList<T>& LinkedList<T>::operator = (LinkedList<T> rhs)
{
std::swap(rhs.head, head);
return *this;
}
*请注意,您需要交换的所有成员使用复制和交换习惯用法的班级,否则您可能会使班级成员的不变量*
这篇关于链表C ++中的赋值运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!