范例:
// Tclass.h
#ifndef __T_CLASS_H__
#define __T_CLASS_H__
template<typename T>
class Tclass
{
public:
Tclass();
~Tclass(); // 如果作为几类,则用: virtual ~Tclass();
void func1(T t);
int func2(T &t);
private: // or protected
T data;
};
template<typename T>
Tclass<T>::Tclass()
{
...
}
template<typename T>
Tclass<T>::~Tclass()
{
...
}
template<typename T>
void Tclass<T>::func1()
{
...
}
template<typename T>
int Tclass<T>::func2()
{
...
}
#endif
二、
继承用法
// child.h
#ifndef __CHILD_H__
#define __CHILD_H__
typdef struct _ST
{
...
}St;
class Child : public Tclass<St>
{
public:
// 注意这里,Child的实现可以放在cpp中的。
Child() : Tclass<St>::Tclass()
{}
~child();
...
private:
...
}
#endif
三、
问题:为什么模板类的.cpp 与.h文件不能分开
1.
在某些编译器中是可以分开,但是在很多的编译器中是不可以分开的。
虽然某些编译器在模板这种情况下做了支持可以将函数的实现和声明的分开,但是个人认为这并不是一个很好的做法。
2.
我们都知道,在编译的时候,并不对模板本身进行编译。它就像一个未装填任何东西的空箱子,是不需要搬到可执行文件这辆卡车上的。
但当有一个确定的类型被装进了模板的这个箱子中时候,编译器就非常确定了该实例占用的空间大小等(即箱子的重量等)信息,这时候编译器才会将该模板按照一定的方式进行展开编译实现。
3.
这样看来,模板的整个声明与实现,其实完全都是一个声明,因为没有确定的数据类型,所以在实例之前,编译器无法知道该模板应以什么样的方式去编译。这样理解起来,那么模板类所有的信息,理应都放在头文件中。
4.
对于某些编译器对这种分离的支持,实在是会误导我们对模板类的理解。
5.
有些巧妙的方法是,在头文件最后面包含cpp文件。还有些是直接在使用的时候包含cpp文件。其实都是告诉编译器,这只是一个头文件的声明而已,没有实现过程。
四、
摘自: http://col1.blog.163.com/blog/static/19097751920127604811213/
泛型是概念, 模板是泛型的实现
泛型编程让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。
泛型编程的代表作品STL是一种高效、泛型、可交互操作的软件组件。
所谓泛型(Genericity),是指具有在多种数据类型上皆可操作的含意,与模板有些相似。
STL巨大,而且可以扩充,它包含很多计算机基本算法和数据结构,而且将算法与数据结构完全分离,其中算法是泛型的,不与任何特定数据结构或对象类型系在一起。
STL以迭代器(Iterators)和容器(Containers)为基础,是一种泛型算法(Generic Algorithms)库,容器的存在使这些算法有东西可以操作。
STL包含各种泛型算法(algorithms)、泛型指针(iterators)、泛型容器(containers)以及函数对象(function objects)。
STL并非只是一些有用组件的集合,它是描述软件组件抽象需求条件的一个正规而有条理的架构。