Я использую шаблоны в C++ для создания связанного списка. Я закодировал несколько функций, но удаление узла (либо из головы/хвоста) не работает должным образом. Он отображает ошибку и завершается. При отладке «это», отображаемое в окнах часов, содержит голова, которая равна нулю, и я не знаю, почему. Вот мой код:Удаление узлов в связанном списке не работает?
SLlistSc.h
#ifndef SLlistSc_H
#define SLlistSc_H
#include<iostream>
using namespace std;
template<class T> class SLlist;
template <class T> class snode{
friend class SLlist<T>;
private:
T info;
snode<T> *next;
public:
inline T getter() const { return info; }
inline void setter(T setValue){ info = setValue; }
snode(){ info = 0; next = 0; }
snode(T inf , snode *nex = 0){ info = inf; next = nex; }
~snode(){ delete next; }
};
template <class T> class SLlist{
private:
snode<T> *head, *tail;
static int total;
public:
SLlist(){ head = tail = 0; }
~SLlist(){
snode<T> *p = head;
while (head != 0){
head = head->next;
delete p;
p = head;
}
}
inline void incrcnt(){ total++; }
inline void decrcnt(){ total--; }
void displayList();
void addToHead(T inf);
void addToTail(T inf);
T deleteFromHead();
T deleteFromTail();
int returnIndex();
void deleteInfo();
void deleteAll();
};
template <class T> void SLlist<T>::displayList(){
snode<T> *p = head;
while (p != 0){
cout << "\n->" << p->info;
p = p->next;
}
return;
}
template <class T> void SLlist<T>::addToHead(T inf){
snode<T> *temp = new snode<T>(inf, 0);
if (head == 0){ head = tail = temp; temp = 0; delete temp; incrcnt(); return; }
else { temp->next = head; head = temp; temp = 0; delete temp; incrcnt(); return; }
}
template <class T> void SLlist<T>::addToTail(T inf){
snode<T> *temp = new snode<T>(inf, 0);
if (head == 0){ head = tail = temp; temp = 0; delete temp; incrcnt(); return; }
else{ tail->next = temp; tail = temp; temp = 0; delete temp; return; }
}
template <class T> T SLlist<T>::deleteFromHead(){
if (head == 0){ cout << "\nList is already empty"; return (T)0; }
if (head == tail){ delete head; head = tail = 0; T info = head->info; return info; }
else {
T info = head->info;
snode<T> *temp = head;
head = head->next;
temp = 0;
delete temp;
return info;
}
}
template <class T> T SLlist<T>::deleteFromTail(){
if (head == 0){ cout << "\nList is already empty"; return (T)0; }
if (head == tail){ delete head; head = tail = 0; T info = head->info; return info; }
else {
T info = tail->info;
snode<T> *temp = head;
while (temp != 0)
{
temp = tail;
}
delete tail;
tail = temp;
temp = 0; delete temp;
return (T)info;
}
}
#endif
и файл CPP: SLlistSc.cpp
// SLlistSc.cpp : Defines the entry point for the console application.
//
#include"SLlistSc.h"
#include<iostream>
using namespace std;
template <class T> int SLlist<T>::total = 0;
void main()
{
cout << "\t\t\t Singly Linked List Super Class Implementation";
SLlist<int> List1;
int userchoice=0, inf=0;
do{
cout << "\n\n\t\t Menu"
<< "\n\t1. Display List"
<< "\n\t2. Add to Head"
<< "\n\t3. Add to tail"
<< "\n\t4. Delete from Head"
<< "\n\t5. Delete from Tail"
<< "\n\t6. Exit";
cin >> userchoice;
switch (userchoice){
case 1: List1.displayList(); break;
case 2: cout << "\nEnter info to be added:";
cin >> inf;
List1.addToHead(inf); break;
case 3: cout << "\nEnter info to be added:";
cin >> inf;
List1.addToTail(inf); break;
case 4: inf = List1.deleteFromHead();
cout << "\n Value" << inf << "deleted from list"; break;
case 5: inf = List1.deleteFromTail();
cout << "\n Value" << inf << "deleted from list"; break;
case 6: cout << "\n\t\t\t\tExiting";
exit(0);
default: continue;
}
} while (userchoice < 4);
}
Другое дело, я хотел бы спросить, когда мы используем шаблоны на классе (например, класс А), мы должны заменить А на А всюду. Это потому, что компилятор генерирует новый класс, т.е.
<T> разве = A.
И в то время как с помощью друга класса SLlist внутри класса snode, почему я должен заявить следующее:
template<class T> class SLlist;
перед классом snode ? почему не могу я объявляю его непосредственно в классе snode как:
friend class SLlist<T>;
Кроме того, если есть шанс improvemet в моем коде, пожалуйста, идти тяжело на меня. Благодарю.
* Он отображает сообщение об ошибке и завершает * - какова ошибка? –
«Необработанное исключение в 0x01323DB6 в файле SLlistSc.exe: 0xC0000005: место чтения нарушения доступа 0xFEEEFEF2». Это как-то связано с «этим» указателем, отображаемым в окне часов, поскольку у него есть нуль как в голове, так и в хвосте, я не знаю почему? –
Я думаю, что вы делаете двойное удаление своих узлов. Деструктор узла удаляет узлы, а затем ваш деструктор списка удаляет узлы. – pstrjds