函数指针——指针函数
数组指针——指针数组
类模板——模板类
函数模板——模板函数
1.函数指针——指针函数
函数指针的重点是指针。表示的是一个指针,它指向的是一个函数,例子:
int (*pf)();
指针函数的重点是函数。表示的是一个函数,它的返回值是指针。例子:
int* fun();
2.数组指针——指针数组
数组指针的重点是指针。表示的是一个指针,它指向的是一个数组,例子:
int (*pa)[8];
指针数组的重点是数组。表示的是一个数组,它包含的元素是指针。例子;
int* ap[8];
3.类模板——模板类(class template——template class)
类模板的重点是模板。表示的是一个模板,专门用于产生类的模子。例子:
template <typename T>
class Vector
{
…
};
使用这个Vector模板就可以产生很多的class(类),Vector<int>、Vector<char>、Vector< Vector<int> >、Vector<Shape*>……。
模板类的重点是类。表示的是由一个模板生成而来的类。例子:
上面的Vector<int>、Vector<char>、……全是模板类。
关于一个缺省模板参数的例子:
template <typename T = int>
class Array
{
…
};
第一次我定义这个模板并使用它的时候,是这样用的:
Array books;//我认为有缺省模板参数,这就相当于Array<int> books
上面的用法是错误的,编译不会通过,原因是Array不是一个类。正确的用法是Array<> books;
这里Array<>就是一个用于缺省模板参数的类模板所生成的一个具体类。
4.函数模板——模板函数(function template——template function)
函数模板的重点是模板。表示的是一个模板,专门用来生产函数。例子:
template <typename T>
void fun(T a)
{
…
}
在运用的时候,可以显式(explicitly)生产模板函数,fun<int>、fun<double>、fun<Shape*>……。
也可以在使用的过程中由编译器进行模板参数推导,帮你隐式(implicitly)生成。
fun(6);//隐式生成fun<int>
fun(8.9);//隐式生成fun<double>
fun(‘a’);// 隐式生成fun<char>
Shape* ps = new Cirlcle;
fun(ps);//隐式生成fun<Shape*>
模板函数的重点是函数。表示的是由一个模板生成而来的函数。例子:
上面显式(explicitly)或者隐式(implicitly)生成的fun<int>、fun<Shape*>……都是模板函数。
关于模板本身,是一个非常庞大的主题,要把它讲清楚,需要的不是一篇文章,而是一本书,幸运的是,这本书已经有了:David Vandevoorde, Nicolai M. Josuttis写的《C++ Templates: The Complete Guide》。可惜在大陆买不到纸版,不过有一个电子版在网上流传。
模板本身的使用是很受限制的,一般来说,它们就只是一个产生类和函数的模子。除此之外,运用的领域非常少了,所以不可能有什么模板指针存在的,即指向模板的指针,这是因为在C++中,模板就是一个代码的代码生产工具,在最终的代码中,根本就没有模板本身存在,只有模板具现出来的具体类和具体函数的代码存在。
但是类模板(class template)还可以作为模板的模板参数(template template parameter)使用,在Andrei Alexandrescu的《Modern C++ Design》中的基于策略的设计(Policy based Design)中大量的用到。
template< typename T, template<typename U> class Y>
class Foo
{
…
};
从文章的讨论中,可以看到,名字是非常重要的,如果对名字的使用不恰当的话,会引起很多的麻烦和误解。我们在实际的程序中各种标识符的命名也是一门学问,为了清晰易懂,有时候还是需要付出一定的代价。
最后提醒:在本文的几个术语中,语言的重心在后面,前面的词是作为形容词使用的。