本例中我们定义了三个独立的Array 类模板的实例:
Array<int> ia(array_size);
Array<double> da(array_size);
Array<char> ca(array_size);
这些实例声明就是在类模板名的后面加上一对尖括号,然后在里面写上数组的实际类型。
当我们定义类模板对象如ia、da或ca 时会发生什么事情呢?编译器必须为相关的对象
分配内存,为了做到这一点,形式模板参数被绑定到指定的实际参数类型上,对ia 来说Array
类模板通过将elemType 绑定到类型int 上产生如下的类数据成员:
// Array<int> ia(array_size);
int _size;
int *ia;
结果是一个类,它与我们前面手工编码实现的IntArray 类等价,对da 来说通过将
elemType 绑定到类型double 上,成员变为
// Array<do uble> da(array_size);
int _size;
double *ia;
类似地对ca 来说通过将elemType 绑定到类型char 上,成员变为
// Array<char> ca(array_size);
int _size;
char *ia;
类模板的成员函数会怎么样呢?不是所有的成员函数都能自动地随类模板的实例化而被
实例化。只有真正被程序使用到的成员函数才会被实例化,这一般发生在程序生成过程中的
一个独立阶段,16.8 节将详细讨论这个过程。
编译并运行程序会产主如下结果
[ 0 ] ia: 0 ca: a da: 0
[ 1 ] ia: 1 ca: b da: 1.75
[ 2 ] ia: 2 ca: c da: 3.5
[ 3 ] ia: 3 ca: d da: 5.25
模板机制也支持面向对象的程序设计,类模板可以作为基类或派生类,下面是一个带有
范围检查的Array 类模板的定义
#include <cassert>
#include "Array.h"
template <class elemType>
class ArrayRC : public Array<elemType> {
public:
ArrayRC( int sz = Array<elemType>::DefaultArraySize )
: Array< elemType >( sz ){};
ArrayRC( elemType *ia, int sz )
: Array< elemType >( ia, sz ) {}
ArrayRC( const ArrayRC &rhs )
: Array< elemType >( rhs ) {}
virtual elemType&
operator[]( int index )
{
assert( index >= 0 && index < Array<elemType>::size() );
return ia[ index ];
}
private:
// ...
};