链表C++中的赋值运算符
Assignment operator in linked list C++
我正在尝试在c ++中实现链表。
我像这样实现我的赋值运算符:
// 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;
}
在我的主函数中,我使用以下代码进行测试:
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
但是当程序尝试删除lst2时,我收到一条错误消息:
未分配正在释放的指针
我使用调试器并找出程序何时执行分配:
lst1 = lst2;
lst1 实际上指的是指向 lst2 而不是获取 lst2 副本的地址,因此当我删除 lst1 时,lst2 已经消失了。
那么谁能告诉我我的分配运算符出了什么问题?
如果这是一个新手问题,我很抱歉,但我已经花了几个小时,无法弄清楚。
我完成的代码如下所示:
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;
}
}
您当前的实现复制了复制构造函数中已经存在的代码,那么为什么不重用它呢?
如果你有一个工作的副本构造函数和析构函数,使用复制/交换习惯用法将是实现赋值运算符的最简单、最安全的方法。
#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
中的旧数据。
如果您有 C++ 11 编译器,则可以利用按值传递的传入参数的移动构造。
#include <algorithm>
//...
template<class T>
LinkedList<T>& LinkedList<T>::operator = (LinkedList<T> rhs)
{
std::swap(rhs.head, head);
return *this;
}
* 需要注意的是,在使用 copy and swap 习语时,需要交换类的所有成员,否则可能会使类成员的不变量无效 *
相关文章:
- 重载Singly Linked List中的赋值运算符
- 使用赋值运算符重载从类中返回jobject
- 标准库类型的赋值运算符的引用限定符
- 复制构造函数、赋值运算符C++
- 标准::变体的赋值运算符
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 基类和派生类的多态赋值运算符
- 为用户定义的类正确调用复制构造函数/赋值运算符
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- 为什么初始化时没有调用重载赋值运算符?
- 赋值运算符重载和自赋值
- C++矢量复制构造函数和赋值运算符是否也复制保留空间?
- Qt PL/SQL - 赋值运算符 - 字符串缓冲区太小
- 对 r 值使用移动赋值运算符时的异常
- 由于没有使用赋值运算符,映射的值是如何初始化的?
- 默认赋值运算符如何在实际 STL 中实现
- 使用赋值运算符复制 std::vector
- C++ 通过自定义赋值运算符隐式转换函数参数
- 赋值运算符的奇怪行为
- C++赋值运算符,我们可以用 copy 替换它吗?