template
class btnode{
public:
private:
valtype _val;
int _cnt;
btnode *_lchild;
btnode *_rchild;
};
在class template中,valtype相当于一个占位符,其名称可以任意设定。
为了通过class template实例化类,必须在class template名称之后,紧接一个尖括号,其中放置一个实际的类型。
btnode bti;
btnode bts;
通过int和string来替代valtype这个占位符
在声明玩btnode之后,再声明binarytree 这个class template
template
class binarytree{
public:
private:
btnode *_root; //btnode必须以template 参数列表的形式限定
};
这样才能保证,binarytree的类型和btnode的类型保持一致
template
class binarytree{
public:
binarytree();
binarytree(const binarytree&);
~binarytree();
binarytree& operator=(const binarytree&);
bool empty() {
return _root==0;
}
void clear();
private:
btnode *_root;
void copy(btnode *tar,btnode *src);
};
在类中定义一个inline函数,其做法和普通的非模板类是一样的,但是在类外,定义的方式不大相同
template
inline binarytree::binarytree:_root(0){
}
也就是在定义class template时,需要先指定template的占位符,然后在声明scope的时候,也需要将占位符体现出来。binarytree
在构造函数中,应该在成员初始化列表中为每个类型参数进行初始化,也就是通过typename定义的量。
template
inline btnode::btnode(const valtype &val):_val(val){
_cnt=1;
_lchild=_rchild=0;
}
因为如果在构造函数的函数体类定义,如果val是class类型的,那么这个初始化方式可能存在问题。
在上面的程序中,val是通过占位符valtype来定义的,其参数类型不确定,因此最好使用成员初始化列表来进行初始化
template
inline void binarytree::insert(const elemtype &elem){
if(_root)
_root=new btnode(elem);
else
_root->insert_value(elem);
}
new表达式可以分解为两个操作:
1.向程序的空闲空间请求内存,如果分配到足够的空间,就返回一个指针,指向新的对象,如果空间不足,就抛出异常
2.如果第一步成功,并且外界指定了一个初值,这个新对象便会以适当的方式被初始化。
为binarytree 这个class template定义output运算符
template
inline ostream& operator <<(ostream &os,const binarytree &bt){
os<< "tree: "<
template参数并不是非要某种类型,也可以使用常量表达式作为template的参数
template
class num_sequence{
num_sequence(int beg_pos=1);
};
template
class Fibonacci:public num_sequence{
Fibonacci(int beg_pos=1):num_sequence(beg_pos){
}
};
其中,int len相当于在类的内部定义了一个变量,也就是在定义类的时候就给出了这个成员变量len。