上次我们已经讲述了使用类模板的好处,今天我们来讲解一下如何定义和使用类模板?
类模板的定义和类的定义很相似,唯一不同的地方是类模板需要使用template关键字来引出类模板需要使用的抽象类型。
类模板定义的语法大致如下:
template<模板参数类型列表>
class 模板类名
{
...
};
为了方便大家的理解,我们通过实际的例子来讲解。
例1 定义和使用栈类模板
MyStack.hpp的内容:
#ifndef _MYSTACK_HPP_
#define _MYSTACK_HPP_
#include<iostream>
using namespace std;
template<typename T> class CMyStack;
template<typename T>
class CNode
{
public:
CNode(T v) :m_Data(v), m_pNext(NULL){};
protected:
T m_Data;
CNode * m_pNext;
friend class CMyStack<T>;
};
template<typename T>
class CMyStack
{
public:
CMyStack():m_pFirst(NULL){};
~CMyStack()
{
CNode<T> * pTemp = m_pFirst;
while (pTemp)
{
m_pFirst = m_pFirst->m_pNext;
delete pTemp;
pTemp = m_pFirst;
}
}
bool Push(T node);
T Top() throw (std::runtime_error);
void Pop();
bool IsEmpty();
void Print();
protected:
CNode<T> * m_pFirst;
};
template<typename T>
bool CMyStack<T>::Push(T Node)
{
CNode<T> * pNewNode = new CNode<T>(Node);
if (!pNewNode)
{
return false;
}
pNewNode->m_pNext = m_pFirst;
m_pFirst = pNewNode;
return true;
}
template<typename T>
T CMyStack<T>::Top() throw (std::runtime_error)
{
if (!m_pFirst)
{
throw std::runtime_error("stack is empty.");
}
return m_pFirst->m_Data;
}
template<typename T>
void CMyStack<T>::Pop()
{
T val;
CNode<T> * pTempNode = m_pFirst;
if (!m_pFirst)
{
return;
}
m_pFirst = m_pFirst->m_pNext;
delete pTempNode;
pTempNode = NULL;
return;
}
template<typename T>
bool CMyStack<T>::IsEmpty()
{
if (!m_pFirst)
{
return true;
}
return false;
}
template<typename T>
void CMyStack<T>::Print()
{
CNode<T> * pTempNode = m_pFirst;
while (pTempNode)
{
cout << pTempNode->m_Data << "\t";
pTempNode = pTempNode->m_pNext;
}
cout << endl;
}
#endif
main.cpp的内容:
#include "MyStack.hpp"
void main()
{
CMyStack<int> IntStack;
CMyStack<float> FloatStack;
IntStack.Push(1);
IntStack.Push(2);
IntStack.Push(3);
IntStack.Push(4);
IntStack.Push(5);
cout << "整型栈:" << endl;
IntStack.Print();
while (!IntStack.IsEmpty())
{
cout << "栈顶" << IntStack.Top() << endl;
cout << "出栈" << endl;
IntStack.Pop();
}
FloatStack.Push(1.1);
FloatStack.Push(2.2);
FloatStack.Push(3.3);
FloatStack.Push(4.4);
FloatStack.Push(5.5);
cout << "浮点栈:" << endl;
FloatStack.Print();
while (!FloatStack.IsEmpty())
{
cout << "栈顶" << FloatStack.Top() << endl;
cout << "出栈" << endl;
FloatStack.Pop();
}
system("pause");
}
运行效果如图1所示:
图1 栈类模板的运行效果
在例1中,MyStack.hpp定义了一个栈类模板CMyStack,main.cpp使用了栈类模板CMyStack。栈类模板的定义首先以template开头,后追加一对尖括号,尖括号中输入模板参数,之后模板的定义和类的定义基本一致。另外还需要强调的一点是,如果将模板类中的成员函数放在模板类之外定义,需要在函数定义之前写上template,后追加一对尖括号,尖括号中输入模板参数,同时模板类名后也要追加一对尖括号,尖括号中输入模板参数。
在例1中,main.cpp通过模板类名,后追加一对尖括号,尖括号中输入类模板实参,之后模板类对象的使用方式和普通类对象的使用方式一致。
小结
今天,我们主要讲述了如何定义一个类模板以及如何使用类模板。希望大家回去实践一下,加深体会。