上次我们已经讲述了使用类模板的好处,今天我们来讲解一下如何定义和使用类模板?
类模板的定义和类的定义很相似,唯一不同的地方是类模板需要使用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 << " "; pTempNode = pTempNode->m_pNext; } cout << endl; } #endifmain.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通过模板类名,后追加一对尖括号,尖括号中输入类模板实参,之后模板类对象的使用方式和普通类对象的使用方式一致。
小结
今天,我们主要讲述了如何定义一个类模板以及如何使用类模板。希望大家回去实践一下,加深体会。