【发布时间】:2013-11-06 02:35:50
【问题描述】:
我在为链表实现重载 = 运算符时遇到问题。 List 类包含一个Node* head 指针和一个包含T* data 和Node* next 的struct Node,其中T 是模板类型名。我对操作符函数末尾发生的事情有疑问,其中析构函数(在本例中由makeEmpty 处理)在操作符末尾被调用两次,一次是在遍历列表并创建一个新的之后相同节点的列表,并且在运算符函数退出后一次。
这里是 makeEmpty 的实现:
// Does the work of the Destructor
template <typename T>
void List<T>::makeEmpty() {
cout << endl << endl << "DESTRUCTOR CALLED" << endl << endl;
List<T>::Node* tempPtr = head;
if (head != NULL) {
List<T>::Node* nextPtr = head->next;
for(;;) {
if (tempPtr != NULL) {
delete tempPtr->data;
tempPtr = nextPtr;
if (nextPtr != NULL)
nextPtr = nextPtr->next;
/*tempPtr = head->next;
delete head;
head = tempPtr;*/
}
else break;
}
}
}
这里是 operator= 重载实现:
// Overloaded to be able to assign one list to another
template <typename T>
List<T> List<T>::operator=(const List& listToCopy) {
List<T> listToReturn;
listToReturn.head = NULL;
List<T>::Node* copyPtr = listToCopy.head;
List<T>::Node* thisPtr = head;
if (copyPtr != NULL && thisPtr != NULL) {
for(;;) {
if (copyPtr != NULL) {
T* toInsert = new T(*copyPtr->data);
listToReturn.insert(toInsert);
copyPtr = copyPtr->next;
}
else{cout << endl << listToReturn << endl << endl; return listToReturn;}
}
}
// if right-hand list is NULL, return an empty list
return listToReturn;
}
我已经调试了一段时间,似乎第二次调用析构函数时,被销毁的列表的头部包含不可读的内存。我什至不确定为什么在运算符中调用了两次析构函数,因为唯一需要销毁的列表是返回后的 listToReturn 。 (也许我的逻辑在某个地方有缺陷……我只是想这个问题太久了)
如果你们需要更多关于代码的信息,我很乐意提供。像往常一样,这是一个任务,所以我只要求可以帮助我走向正确方向的提示。所以感谢大家的关注和帮助!
【问题讨论】:
-
你和this questioner 真的需要聚在一起。并在您的问题中包含
List的 full 模板类声明。我可以看到您已经拥有不需要的一级动态分配。List<T>::Node::data完全没有理由是动态的,除非你能想到一个很好的理由来分配一个没有数据的Node(顺便说一句,没有一个)。 -
你应该在赋值运算符中返回
List<T>&
标签: c++ linked-list operator-overloading