用C++封装一个不带头结点的单链表
要求:用嵌套类型的方式
template<typename T>
class CLink//模板
{
public:
CLink()
{
phead = NULL;
}
~CLink()
{
Node* pCur = phead;
Node* pNext;
while (pCur != NULL)
{
pNext = pCur->pnext;
delete pCur;
pCur = pNext;
}
phead = NULL;
}
void insertHead(T val)
{
Node* pnewnode = new Node(val);
pnewnode->pnext = phead;
phead = pnewnode;
}
void insertTail(T val)
{
Node* pnewnode = new Node(val);
if (phead == NULL)
{
phead = pnewnode;
}
else
{
Node* ptail = phead;
while (ptail->pnext != NULL)
{
ptail = ptail->pnext;
}
ptail->pnext = pnewnode;
}
}
void Show()
{
Node* pCur = phead;
while (pCur != NULL)
{
std::cout << pCur->mdata << " ";
pCur = pCur->pnext;
}
std::cout << std::endl;
}
private:
class Node//类
{
public:
Node(T val = T())
:mdata(val), pnext(NULL)
{}
public://任意位置
T mdata;
Node* pnext;
};
Node* phead;//phead 头指针
};
1、以嵌套的方式的好处是:
在使用两个不同的类时,不用考虑是否存在不能访问某一个类私有成员变量的情况,也就是不用写友元函数。
2、此时class作为一个模板,而Node作为一个类类型。
如果要在函数模板中写一个查询函数
要求:返回查询到的第一个数组当前的结点位置
一般我们会直接在模板下写:
Node* find(T val)
{
Node* pCur = phead;
while (pCur != NULL)
{
if (pCur->mdata == val)
{
return pCur;
}
pCur = pCur->pnext;
}
return NULL;
}
1、编译器报错:
2、以上错误的原因是:
在C++中类的编译过程:
(1)类名
(2)成员名称
(3)成员函数的返回值和形参
(4)成员函数的函数体
在编译过程中,Node类是一个局部类,是在编译第3步完成后才进行编译的,但是在进行第3步时,编译器并不认识Node类
3、如果将查询函数放在类外实现,此时代码改为:
template<typename T>
CLink<T>::Node* CLink<T>::find(T val)
{
Node* pCur = phead;
while (pCur != NULL)
{
if (pCur->mdata == val)
{
return pCur;
}
pCur = pCur->pnext;
}
return NULL;
}
程序报错:
此时,Node还未编译,编译器并不知道Node是不是类型,
改正:给前面加上typename。
template<typename T>
typename CLink<T>::Node* CLink<T>::find(T val)
此时,第一个typename是定义了模板类型参数,第二个typename是声明了Node类是属于CLink类中的一个类型。
4、总结:
typename 声明模板中的一个类型