C++-模板

/**/ /**********************************************************************
*  <模板>                                                                                              
*模板是一种参数化的类或函数,也就是类的形态或者函数的形态可以被参数改变.
**********************************************************************
*/


/**/ /**********************************************************************
*  <模板函数>  
*/
                                                                                             

 template 
< class  T >  T funname(para type)

/**/ /*自我理解:
*       如果要计算int型和float型数组的平均值,可以分别写int_average(int nVal,*int size)和
*float_average(int nVal,int size)两个函数,但其实它们里面的步骤是一*样的,只是数据类型
*不同,如果使用模板,就不需要这么麻烦了。
**********************************************************************
*/

// 例1:
 template  < class  T >  average(T  * array, int  size) 
 ...
{
  T sum 
= 0;
  
for(int i=0;i<size;i++)
   sum 
+= array[i];
  T avg 
= sum/size;
  
return avg;
 }
;
// "<class T>"告诉编译器"T"是函数使用的数据类型。

// 提示:模板函数最好写在头文件中,但必须要写在main()前面

// 例2:
 template  < class  T >
 T max(T x,T y) 
// 传入的参数改必须是同类型的
 ... {
  
return (x>y)  ? x:y;
 }


 
void  main()
 ...
{
  
double a = 50.235;
  
double b = 50.234;
  
double c = max(a,b);
  cout
<<"最大值="<<c<<endl;
 }


// 函数模板经实例化所生成的具体函数叫"模板函数";
// 例如例1,可以实例化成 average(int,int)、average(float,float)、average(char,char) 等等...
// 每一个模板形参前必须有"class"关键字!
// 在template语句与函数模板语句之间不允许有别的语句;


/**/ /**********************************************************************
*  <多类型模板函数>  
*
*       如上题数组,若数组中所有元素之和超过类型范围怎么办?可用多类型*函数模板解决 
**********************************************************************
*/

// 例:
 template  < class  T1, class  T2 >
 T1 average(T1 
* array,T2, int  size) // 声明函数模板
 ... {
  T2 sum 
= 0;   
  
for(int i=0;i<size;i++)
   sum
+=array[i];
  
return(sum/i);
 }

 
void  main()
 ...
{
  __int16 intArray[]
=...{10000,20000,30000}// 范围 -32768 - 32767
  cout<<"整数平均值="<<::average(intArray,0,3)<<endl;
 }


/**/ /* 自我理解
    此例中,当T1接收了__int16 intArray[]后,它俨然就成了__int16型了,但要命的是,数组中的
数字相加后,会超界,so...再定义一个T2,用T2来接收相加后的的数据,T2会根据数据的大小来
确定自己的类型。 
*/



/**/ /**********************************************************************
*  <模板函数的重载>  
*       因为模板函数需要接收同类型的参数,要是参数类型不一致怎么办?可以使用函数重载.
**********************************************************************
*/

 template
< class  T >

 T max(T x,T y) 
// 传入的参数改必须是同类型的
 ... {
  
return (x>y) ? x:y ;
 }


 
int  max( int  x , char  y)  // 重载函数 max,一个整型参数,一个字符型参数
 ... {
  
return (x>y) ? x:y ;
 }


 
void  main()
 ...
{
  
int a = 55;
//     int b = 66;
  char b = 'A'//ASCII 码 65
  cout<<"最大值="<<max(a,b)<<endl;  //此处将调用重载函数
 }



/**/ /**********************************************************************
*  <类模板>  
**********************************************************************
*/

 
const   int  size  =   10 ;
 template 
< class  T >
 
class  stack
 ...
{
  T stck[size]; 
//模板定义数组的数据类型
 public:
  
//若成员函数中使用了模板,则此函数需要在类体外定义!!!
  void push(T ch); //模板定义形参类型
  T pop(); //模板定义返回类型
 }
;

 template 
< class  T >    // 注意:在类体外实现成员函数时的写法!!!
  void  stack < T > ::push(T ob)
 ...
{
 }


 template 
< class  T >   // 注意:在类体外实现成员函数时的写法!!!
 T stack < T > ::pop()
 ...
{
  T a 
= 0;
  
return a;
 }

 
void  main()
 ...
{
  stack
<int> a; //对象的定义
  
//stack<int> a,b;
  
//stack<double> b;
 }


/**/ /**********************************************************************
*  <多参数类模板>  
* template <class T,T t> 或者 template <class T,int size>
*      参数的名字在整个模板的作用域内都有效,类型参数可以作用作用域变量的类型,数值型
*参数可以参与计算,就像使用一个普通常数一样(例如 cout<<t<<endl;)
**********************************************************************
*/

 
// 多参数模板
template  < class  T, int  size >   // 第一个参数是类型,第二个参数是数值(必须是常量)
  class  stack
 ...
{
    T stck[size];
    
public:
    
void push(T x);
    T pop();
    
void print()
    ...
{
        cout
<<size<<endl;
    }

 }
;

 template 
< class  T, int  size >   // 注意写法!!!
  void  stack < T,size > ::push(T x)
 ...
{
 }


 template 
< class  T, int  size >    // 注意写法!!!
 T stack < T,size > ::pop()
 ...
{
    T a 
= 0;
    
return a;
 }


 
void  main()
 ...
{
    stack
<int,10> a1,a2; //合法,对象的定义

    
int x = 100;
    stack
<int,x> b1; //不合法,x必须是常量

    
const int y = 100;
    stack
<int,y> c1; //合法.

    a1.print();
 
//    stack<double,5> b1,b2; //对象的定义
 }



/**/ /**********************************************************************
*模板总结:
*      模板提供了代码复用.在使用模板时首先要实例化,即生成一个具体的函数或类.函数模
*板的实例化是隐式实现的,即由编译系统根据对具体模板函数(实例化后的函数)的调用来进
*行相应的实例化,而类模板的实例化是显示进行的,在创建对象时由程序指定.
*
*      以前我一直以为模板的方法全部都是隐含为inline(内联,就是函数体定义在类之外,提高
*函数的执行效率)的,其实并非如此(Thinking C++[2]中有提到模板的non-inline function).所以
*我们一般在后缀为 .i 或者 .inl的文件中完成模板类方法的实现.
*例: //in temp.h                         //in temp.inl  
*  template<class T>    template<class T>
*  class Temp       void Temp<class T>::print() 
*  {          {...}
*  public:
*   void print();
*  }
*  #include "temp.inl"
*
*语法检查
*     对模板语汇法的检查会被延迟到使用的时刻,而不像一般的类或函数在编译器读到时就
*检查,所以如果你定义了一个模板,且语法错误,但你却没有去用它,编译时不会报错.
*
*继承
*      模板类和普通的类一样,也可以有派生类.且它的基类和派生类既可以是模板类,也可以不
*是模板类.
* class Abase 
* {...};
* template<classT> 
* class A:public Abase
* {...};
**********************************************************************
*/

// 模板小练习

template
< class  T >
T sum(T x,T y)
{
    
return x+y;
}


void  main()
{
    
int a = 100;
    
int b = 200;
    
int c = sum(a,b);
    cout
<<"总和="<<c<<endl;
}




template 
< class  T1, class  T2 >
T1 average(T1 
* x,T2 y, int  size)
{
    T2 sum 
= 0;
    
for(int i=0;i<size;i++)
    
{
        sum 
+= x[i];
    }

    
return sum / size;
}


void  main()
{
    __int16 array[] 
= {20000,10000,15000};
    __int16 val 
= ::average(array,0,3);
    cout
<<"平均值="<<val<<endl;
}




template 
< class  T, int  size >
class  stack
{
private:
    T size[
100];
public:
    
void push(T);
    T pop();
}
;

template 
< class  T, int  size >
void  stack < T,size > ::push(T ch)
{    
    cout
<<"in the push area"<<endl;
}


template 
< class  T, int  size >
T stack
< T,size > ::pop()
{
    T a 
= 0;
    
return a;
}


void  main()
{
    stack
<int,100> a;
    a.pop();
    a.push(
100);
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值