链表中=操作符重载的意义
Significance of = operator overloading in case of linked lists
我试图在c++中重载=操作符,并编写了以下代码:
template<class T>
class List {
public:
List();
List (T t_data);
List& operator=(const List<T> &L);
private:
template<class L>
class Node {
public:
L data;
Node *next;
Node *prev;
Node(T t_data) {
data = t_data;
next = prev = NULL;
}
};
Node<T> *head;
};
template<class T>
List& List<T>::operator=(const List<T> &L) {
Node<T> *t_head = head;
Node<T> *t_tail = head->prev;
Node<T> *temp;
while(t_head ! = t_tail) {
temp = t_head;
t_head = t_next;
delete temp;
}
head = L.head;
t_head = t_tail = temp = NULL;
return *this;
}
我写这段代码只是为了练习模板、指针和操作符重载,但我想知道在这种情况下=操作符的意义。即使我用
List L1(2);
List L2(3);
L1 = L2;
现在在L1中反映的任何变化都会反映在L2中,所以我们可以这样做
List L1(2);
List *L2 = &L1;
这也将解决上述目的。那么,为什么在许多文章和书籍中,链表的=操作符被重载了呢?
编辑: @T.C。参考您的说明,如果我不将Node
声明为模板,代码将如下所示
class List {
public:
List();
List (T t_data);
List& operator=(const List<T> &L);
private:
class Node {
public:
T data;
Node *next;
Node *prev;
Node(T t_data) {
data = t_data;
next = prev = NULL;
}
};
Node *head;
};
现在如果我在成员函数中声明一个Node对象,如下所示
void List::func() {
Node temp;
…..
}
那么如何解决这个"temp"对象的数据成员"data"的类型是什么?
在c++中,通常的做法是具有值语义,即在L1 = L2;
之后,对L1
的更改将在L2
中看不到,反之亦然。
因此你的operator =
的实现是错误的。它应该做的是:
- 复制存储在其他链表中的节点。
- 销毁当前链表中存储的所有节点
- 将步骤1的副本存储到当前链表
一个常见的习惯用法是复制和交换习惯用法:您创建另一个链表的临时副本(第1点),将当前链表的内容与临时副本(第3点)交换,当赋值函数返回时,临时副本将与赋值给(第2点)的先前链表的内容一起销毁。
你能换个方式吗?当然,但它(1)是非常单一的,(2)需要比你现在所拥有的更多的东西才能正确地完成。例如,当L1
和L2
的析构函数在赋值后运行时,当前operator =
的实现将导致双重删除。您需要在析构函数中使用某种引用计数和附加逻辑,以确保不会删除仍在使用的Node
,同时也不会泄漏内存。
旁注:Node
不应该是模板,因为它不应该存储T
以外的东西
相关文章:
- 重载操作符+:表达式必须是整型或无作用域枚举类型
- 重载操作符
- 如何重载操作符==外模板类使用友元函数
- 重载*操作符,使其在左右两边都工作
- 重载操作符<对于非随机迭代器
- 在c++中重载操作符的时间和原因
- 如何在c++中重载=操作符来通过引用进行复制
- 如何在c++中获取定义为友元的重载操作符的地址
- 使用重载操作符的文件操作表达式没有给出预期的结果
- 重载操作符()
- 重载操作符()并在类内使用
- 类中的重载操作符+
- 定时使用重载操作符
- c++带类的重载操作符
- 用列表容器重载[]操作符
- 重载操作符=
- 任何重载操作符()的静态检测
- 重载操作符以处理类对象
- 在使用另一个类的类中重载操作符==
- 派生类和基类中的重载操作符不同