部分编译器不支持模板类重载“<<”“>>”操作符时,模板函数生命与定义分离,必须在类内部直接实现。
// nodelist.h
#ifndef LISTNODE_H
#define LISTNODE_H
#include <iostream>
template<typename Type> class SingleList;
template<typename Type> class ListNode
{
public:
ListNode() : m_pnext(NULL){}
ListNode(const Type item, ListNode<Type> *next=NULL) : m_data(item), m_pnext(next){}
~ListNode() { m_pnext = NULL; }
public:
Type GetData();
friend class SingleList<Type>;
friend std::ostream& operator << (std::ostream& os, ListNode<Type>& out)
{
os<<out.m_data;
return os;
}
private:
Type m_data;
ListNode *m_pnext;
};
template<typename Type> Type ListNode<Type>::GetData()
{
return this->m_data;
}
#endif // LISTNODE_H
// singlelist.h
#ifndef SINGLELIST_H
#define SINGLELIST_H
#include "listnode.h"
#include <iostream>
template<typename Type> class SingleList
{
public:
SingleList() : head(new ListNode<Type>){}
~SingleList()
{
MakeEmpty();
delete head;
}
public:
void MakeEmpty();
int Length();
ListNode<Type>* Find(Type value, int n);
ListNode<Type>* Find(int n);
bool Insert(Type item, int n=0);
Type Remove(int n=0);
bool RemoveAll(Type item);
Type Get(int n);
void Print();
private:
ListNode<Type>* head;
};
template<typename Type> void SingleList<Type>::MakeEmpty()
{
ListNode<Type>* pdel;
while(head->m_pnext != NULL)
{
pdel = head->m_pnext;
head->m_pnext = pdel->m_pnext;
delete pdel;
}
}
template<typename Type> int SingleList<Type>::Length()
{
ListNode<Type>* pcount = head->m_pnext;
int count = 0;
while(pcount != NULL)
{
count++;
pcount = pcount->m_pnext;
}
return count;
}
template<typename Type> ListNode<Type>* SingleList<Type>::Find(int n)
{
if( n < 0)
{
std::cout << "The n is out of boundary" << std::endl;
}
ListNode<Type>* pf = head->m_pnext;
for(int i = 0; pf != NULL && i < n; i++, pf = pf->m_pnext){;}
if(pf == NULL)
{
std::cout << "Can't find the item" << std::endl;
return NULL;
}
return pf;
}
template<typename Type> ListNode<Type>* SingleList<Type>::Find(Type value, int n)
{
if(n < 1)
{
std::cout << "The n is illegal" << std::endl;
return NULL;
}
ListNode<Type>* pf = head;
int count = 0;
while(count != n && pf)
{
pf = pf->m_pnext;
if( pf->m_data == value)
{
count++;
}
}
if(pf == NULL)
{
std::cout << "can't find the element" << std::endl;
return NULL;
}
return pf;
}
template<typename Type> bool SingleList<Type>::Insert(Type item, int n)
{
if(n < 0)
{
std::cout << "The n is illegal" << std::endl;
return 0;
}
ListNode<Type> *pi = head;
ListNode<Type> *pnode = new ListNode<Type>(item);
if(pnode == NULL)
{
std::cout << __FUNCTION__ << " error " << std::endl;
return 0;
}
for(int i = 0; i < n && pi; i++)
{
pi = pi->m_pnext;
}
if( pi == NULL)
{
std::cout << "The n is illegal" << std::endl;
return 0;
}
pnode->m_pnext = pi->m_pnext;
pi->m_pnext = pnode;
return 1;
}
template<typename Type> bool SingleList<Type>::RemoveAll(Type item)
{
ListNode<Type>* pt = head;
ListNode<Type>* pdel = head->m_pnext;
while(pdel != NULL)
{
if(pdel->m_data == item)
{
pt->m_pnext = pdel->m_pnext;
delete pdel;
pdel = pt->m_pnext;
continue;
}
pt = pt->m_pnext;
pdel = pdel->m_pnext;
}
return 1;
}
template<typename Type> Type SingleList<Type>::Remove(int n)
{
if(n < 0)
{
std::cout << "The n is illegal" << std::endl;
exit(1);
}
ListNode<Type>* pdel = NULL;
ListNode<Type>* ppre = head;
for(int i = 0; i < n && ppre->m_pnext; i++)
{
ppre = ppre->m_pnext;
}
if(ppre->m_pnext == NULL)
{
std::cout << "The n is illegal" << std::endl;
exit(1);
}
pdel = ppre->m_pnext;
ppre->m_pnext = pdel->m_pnext;
Type tmp = pdel->m_data;
delete pdel;
return tmp;
}
template<typename Type> Type SingleList<Type>::Get(int n)
{
if(n < 0)
{
std::cout << "The n is out of boundary" << std::endl;
exit(1);
}
ListNode<Type>* pf = head->m_pnext;
for(int i = 0; i < n; i++)
{
pf = pf->m_pnext;
if(pf == NULL)
{
std::cout << "The n is out of boundary" << std::endl;
exit(1);
}
}
return pf->m_data;
}
template<typename Type> void SingleList<Type>::Print()
{
ListNode<Type>* pp = head->m_pnext;
std::cout << "head";
while(pp != NULL)
{
std::cout << "--->" << pp->m_data;
pp = pp->m_pnext;
}
std::cout << std::endl << std::endl << std::endl;
}
#endif // SINGLELIST_H
// main.cpp
#include <iostream>
#include "singlelist.h"
using namespace std;
int main(int argc, char *argv[])
{
SingleList<int> list;
for(int i = 0; i < 20; i++)
{
list.Insert(i*3, i);
}
for(int i = 0; i < 5; i++)
{
list.Insert(3, i*3);
}
cout << "the length of the list is " << list.Length() << endl;
list.Print();
list.Remove(5);
cout << "the length of the list is " << list.Length() << endl;
list.Print();
list.RemoveAll(5);
cout << "the length of the list is " << list.Length() << endl;
list.Print();
cout << "the third element is " << list.Get(3) << endl;
ListNode<int>* p = list.Find(18, 1);
cout << *p << endl;
list.Find(100);
list.MakeEmpty();
cout << "the length of the list is " << list.Length() << endl;
list.Print();
return 0;
}