当然,如果你足够细心,你一定会好奇,为什么大部分书中的例子,模板的代码都写在头文件中(.h文件),这里我们就讨论模板代码的组织方式。C++支持两种模板代码的组织方式,分别是包含方式(我们使用的就是包含方式)和分离方式。这两种组织方式没有太根本的区别,就是一个将代码全写在头文件中,分离方式是像写类一样声明和定义分别写在头文件(.h文件)和实现文件(cpp文件)中。
下面我们分别讨论下这两种代码组织方式。
1、 包含方式
本专题中,所有的实例代码中的模板代码都是以包含方式组织的。因为好多的编译器(如VC6的cl)并不支持分离方式组织代码,将代码写在头文件也只是方便编译器的预处理工作能方便的将.h文件中的代码根据模板实参的类型生成相应的模板类。
当然,将代码都写在头文件中还有一点点小要求:
A、 如果模板的成员函数写在类外,则需要写成如下样式(见Exp04):
template <typename T>// 每个类外成员函数前都要有这句
Node<T>* CDList<T>::AddTail( T Data )
{
Node<T>* pNewNode = new Node<T>(Data);
if ( m_pTail )
m_pTail->m_pNext = pNewNode;
pNewNode->m_pPrev = m_pTail;
if ( m_pTail == NULL )
m_pHead = pNewNode;
m_pTail = pNewNode;
m_nCount++;
return pNewNode;
}
B、 对于特化的代码则需要在.h文件中声明并在.cpp文件中定义,如果都写在.h文件中编译会报重定义错误。
2、 分离方式
上面已经提到过,所谓的分离方式组织代码,就是将模板的声明和定义分别写在头文件(.h文件)和实现文件(cpp文件)中,需要注意的是,并不是所有的编译器都支持这种写法,目前我只知道GCC支持这种写法。
当然,分离方式组织代码也有个小要求,就是在模板的声明和定义的template关键字前都加上export关键字。比如:
// .h 头文件中
export template <typename T>
class CDList
{
public:
CDList();
virtual ~CDList();
public:
bool Change(int nIndex1,int nIndex2);
void Release();
//增加
Node<T>* AddTail( T Data );
Node<T>* AddHead( T Data );
Node<T>* operator[](int nIndex);
//删除
bool DeleteNode( int nIndex );
void PrintAll();
//查找
Node<T>* FindNode( int nIndex );
};
在实现文件(cpp文件)中。
export template <typename T>// 每个类外成员函数前都要有这句
Node<T>* CDList<T>::AddTail( T Data )
{
Node<T>* pNewNode = new Node<T>(Data);
if ( m_pTail )
m_pTail->m_pNext = pNewNode;
pNewNode->m_pPrev = m_pTail;
if ( m_pTail == NULL )
m_pHead = pNewNode;
m_pTail = pNewNode;
m_nCount++;
return pNewNode;
}
….