函数模板与类模板

类属性用于实现参数化模块,即,给程序模块加上类型参数,使其能对不同类型的数据实施相同的操作,它是多态的一种形式。  
  在C++中,类属性主要体现在类属函数和类属类中。  
  1.函数模板  
  例:排序用函数模板来实现。  
  template   <class   T>  
  void   sort(T   elements[],   unsigned   int   count)  
  {   //取第i个元素  
  elements   [i]    
      //比较第i个和第j个元素的大小  
  elements   [i]   <   elements   [j]    
      //交换第i个和第j个元素  
    T   temp=elements   [i];  
    elements   [i]   =   elements   [j];  
    elements   [j]   =   temp;  
  }  
  ......  
  int   a[100];  
  sort(a,100);  
  double   b[200];  
  sort(b,200);  
  A   c[300];   //类A中需重载操作符:<和=,给出拷贝构造函数  
  sort(c,300);  
   
  函数模板定义了一类重载的函数,使用函数模板所定义的函数(模板函数)时,编译系统会自动把函数模板实例化。  
   
  模板的参数可以有多个,用逗号分隔它们,如:  
  template   <class   T1,   class   T2>  
  void   f(T1   a,   T2   b)  
  {   ......  
  }  
   
  模板也可以带普通参数,它们须放在类型参数的后面,调用时需显式实例化,如:  
  template   <class   T,   int   size>  
  void   f(T   a)  
  {   T   temp[size];  
      ......      
  }  
  void   main()  
  {   f<int,10>(1);  
  }  
   
  有时,需要把函数模板与函数重载结合起来用,例如:  
   
  template   <class   T>  
  T   max(T   a,   T   b)  
  {   return   a>b?a:b;  
  }  
  …  
  int   x,y,z;  
  double   l,m,n;  
  z   =   max(x,y);  
  l   =   max(m,n);  
   
  问题:max(x,m)如何处理?  
   
  定义一个max的重载函数:  
   
  double   max(int   a,double   b)  
  {   return   a>b?a:b;  
  }  
   
  2   类属类  
  类定义带有类型参数,一般用类模板实现。  
  例:定义一个栈类,其元素类型可以变化。  
  template   <class   T>  
  class   Stack  
  {       T   buffer[100];  
      public:  
          void   push(T   x);  
  T   pop();  
  };  
  template   <class   T>  
  void   Stack   <T>::push(T   x)   {   …     }  
   
  template   <class   T>  
  T   Stack   <T>::pop()   {   …   }  
  ……  
  Stack   <int>   st1;  
  Stack   <double>   st2;  
   
  类模板定义了若干个类,类模板的实例化是显式的。  
   
  类模板的参数可以有多个,其中包括普通参数,用逗号分隔它们。并且普通参数须放在类型参数的后面。  
   
  例:定义不同大小的栈模板  
  template   <class   T,   int   size>  
  class   Stack  
  {       T   buffer[size];  
      public:  
          void   push(T   x);  
  T   pop();  
  };  
  template   <class   T,int   size>  
  void   Stack   <T,size>::push(T   x)   {   …     }  
   
  template   <class   T,   int   size>  
  T   Stack   <T,size>::pop()   {   …   }  
  ……  
  Stack   <int,100>   st1;  
  Stack   <double,200>   st2;  
   
  注意:1)类模板不能嵌套(局部类模板)。  
      2)类模板中的静态成员仅属于实例化后的类(模板类),不同实例之间不存在共享。  
   
  3   模板也是一种代码复用机制  
  模板提供了代码复用。在使用模板时首先要实例化,即生成一个具体的函数或类。函数模板的实例化是隐式实现的,即由编译系统根据对具体模板函数(实例化后的函数)的调用来进行相应的实例化,而类模板的实例化是显式进行的,在创建对象时由程序指定。  
  一个模板有很多实例,是否实例化模板的某个实例由使用点来决定,如果未使用到一个模板的某个实例,则编译系统不会生成相应实例的代码。  
  在C++中,由于模块是分别编译的,如果在模块A中要使用模块B中定义的一个模板的某个实例,而在模块B中未使用这个实例,则模块A无法使用这个实例,除非在模块A中也定义了相应的模板。因此模板是基于源代码复用,而不是目标代码复用。  
   
  例:  
  //   file1.h  
  template   <class   T>  
  class   S  
  {     T   a;  
      public:  
        void   f();  
  };  
   
  //   file1.cpp  
  #include   "file1.h"  
  template   <class   T>  
  void   S<T>::f()  
  {   …  
  }  
   
  template   <class   T>  
  T   max(T   x,   T   y)  
  {   return   x>y?x:y;  
  }  
   
  void   main()  
  {   int   a,b;  
      float   m,n;  
      max(a,b);  
      max(m,n);  
      S<int>   x;  
      x.f();  
  }  
   
  //   file2.cpp  
  #include   "file1.h"  
  extern   double   max(double,double);  
   
  void   sub()  
  {   max(1.1,2.2);   //Error,no   appropriate   instance  
      S<float>   x;  
      x.f();   //Error,   corresponding   instance   has   no   appropriate   implementation  
  }

你可能感兴趣的:(c,File,Class,buffer,float)