类模板

来源:互联网 发布:mysql 字段替换字符串 编辑:程序博客网 时间:2024/06/06 04:34

类模板

  类模板,是对一批仅仅成员数据类型不同的类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的类,(这类可以看作是类模板的实例),从而大大提高编程的效率。
  定义类模板的一般形式是:
  template <类型名 参数名1,类型名 参数名2,…>
  class 类名
  {
  类声明体
  };
  例如,template <class T>
  class Smemory
  {…
  public:
  void mput(T x);
  …
  }
  表示定义一个名为Smemory的类模板,其中带类型参数T。
  在类模板的外部定义类成员函数的一般形式是:
  template <类型名 参数名1,类型名 参数名2,…>
  函数返回值类型 类名<参数名 1 参数名 2,…>::成员函数名(形参表)
  {
  函数体
  }
    例如
       template <class TYPE>
       TYPE GetMax(TYPE x, TYPE y)
       { return x>y ? x : y; }
  例如:template <class T>
  void Smemory<T>::mput(T x)
  {…}  
  表示定义一个类模板Smemory的成员函数,函数名为mput,形参x的类型是T,函数无返回值。
  类模板是一个类家族的抽象,它只是对类的描述,编译程序不为类模板(包括成员函数定义)创建程序代码,但是通过对类模板的实例化可以生成一个具体的类以及该具体类的对象。
  与函数模板不同的是:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定,
  其实例化的一般形式是:
  类名 <数据类型 1(或数据),数据类型 2(或数据)…> 对象名
  例如,Smemory<int> mol;
  表示将类模板Smemory的类型参数T全部替换成int 型,从而创建一个具体的类,并生成该具体类的一个对象mol。
  类模板示例:
  类模板定义 定义一个类模板,一般有两方面的内容:
  A. 首先要定义类,其格式为:
  template <class T> //或用 template<typename T>
  class foo
  {
  ……
  }
  foo 为类名,在类定义体中,通用类型T可以作为普通成员变量的类型,还可以作为const和static成员变量以及成员函数的参数和返回类型之用。例如:
  template<class T>
  class Test{
  private:
  T n;
  const T i;
  static T cnt;
  public:
  Test():i(0){}
  Test(T k);
  ~Test(){}
  void print();
  T operator+(T x);
  };
  B. 在类定义体外定义成员函数时,若此成员函数中有模板参数存在,则除了需要和一般类的体外定义成员函数一样的定义外,还需在函数体外进行模板声明
  例如
  template<class T>
  Test<T>::Test(T k):i(k){n=k;cnt++;}
  如果函数是以通用类型为返回类型,则要在函数名前的类名后缀上“<T>” (注:所有函数都要加“<T>” )。例如
  template<class T>
  T Test<T>::operator+(T x){
  return n + x;
  }
  C. 在类定义体外初始化const成员和static成员变量的做法和普通类体外初始化const成员和static成员变量的做法基本上是一样的,唯一的区别是需在对模板进行声明,例如
  template<class T>
  int Test<T>::cnt=0;
  template<class T>
  Test<T>::Test(T k):i(k){n=k;cnt++;}
  类模板的使用:
  类模板的使用实际上是将类模板实例化成一个具体的类,它的格式为:类名<实际的类型>。
  模板类是类模板实例化后的一个产物。说个形象点的例子吧。我把类模板比作一个做饼干同的模子,而模板类就是用这个模子做出来的饼干,至于这个饼干是什么味道的就要看你自己在实例化时用的是什么材料了,你可以做巧克力饼干,也可以做豆沙饼干,这些饼干的除了材料不一样外,其他的东西都是一样的了。
  类模板的派生:
  可以从类模板派生出新的类,既可以派生类模板,也可以派生非模板类。派生方法:
  ⑴ 从类模板派生类模板可以从类模板派生出新的类模板,它的派生格式如下例所示:
  template <class T>
  class base
  {
  ……
  };
  template <class T>
  class derive:public base<T>
  {
  ……
  };
  与一般的类派生定义相似,只是在指出它的基类时要缀上模板参数,即base<T>。
  ⑵ 从类模板派生非模板类 可以从类模板派生出非模板类,在派生中,作为非模板类的基类,必须是类模板实例化后的模板类,并且在定义派生类前不需要模板声明语句:template<class>。例如:
  template <class T>
  class base
  {
  ……
  };
  class derive:public base<int>
  {
  ……
  };
  在定义derive类时,base已实例化成了int型的模板类。
  类模板的作用:
  板是范型编程的基础,所谓范型编程就是用独立与任何特定类型的方式编写代码
  所以简单地说,类是对象的抽象,而模板又是类的抽象,也就用模板能定义出具体类
  再理解深刻点
  在c++里,常说的多态一般分为两种:
  一种是运行时的多态,也就是虚函数体现的多态
  另一种是编译时的多态,也就是范型编程的多态,体现在参数的多态
  在作用上是为了提高编程效率,其实用其他技术也能达到同样的效果