C++模板的理解与使用

最近发现原来学的东西根本都不理解,所以本人正在恶补C++,把自己对C++中概念的最简单粗暴的理解写下来。

有问题的地方还请指出~随时更正

 

模板:顾名思义,就是为了方便以后使用而出现的东西,生活中的模板让我们可以轻松仿照而做出自己的东西,C++中的模板也是类似的。

一句话理解模板,类型参数化,让程序员编写与类型无关的代码。

我们知道任何语言变量都是有类型的,C/C++/Java,包括那些所谓的基于对象的语言JavaScript(var声明一切变量)和Lua(local声明一些变量),其实本质上也是分为整形,字符串等等的。

我们在编写一个函数时,往往要传入不同类型的参数,而在C或者C++这样的语言中,我们一般只能传一种类型的参数,比如:一个简单的比较大小的功能函数

 

int Max(int num1,int num2)
{ 
   return a>b?a:b; 
}

很明显这样的函数只能比较整型变量,如果想比较float ,double等还需要重新写几乎一模一样的代码(逻辑完全相同),所以造成代码冗余重复。

 

这样,模板应运而生,你可以把类型参数化,功能逻辑写好后,相比较什么类型都可以,不是很方便么~

(但是也不能任何情况都这么写,因为有的时候你不希望编码者去把char字符拿来比较,这时候就只写int类型的可以限制错误的范围,否则之后可能会出现不太容易的发现的错误结果,因为这样的情况下编译时没有问题的)

 

所以,下面我们介绍第一种模板——函数模板。格式如下,

 

template <class 形参名,class 形参名,......> 返回类型 函数名(参数列表)

{

      函数体

}

这里的class关键字可以用typename来取代(我们可以暂且认为两者没有区别)

下面直接上代码:min函数模板可以比较任意两个类型的变量。

 

#include <iostream>
Using namespace std;

template <class T>  T  min(T a,T b)
{
    Return a<b?a:b;
}

Void main()
{
  int a=4;
  int b=8;
  cout<<"a,b中比较小的是"<< min(a,b)<<endl;
  double</span> a1=1.0;
  double</span> b1=3.09;
  cout<<"a1,b1中比较小的是"<<min(a1,b1)<< endl;

}

这里的T就是可以变化的类型,假如我们想比较int类型的,那上面模板里的所有T换成int就可以了。

 

注意:不能为同一个模板类型形参指定两种不同的类型,上面的例子中不能写成min(a,b1);

如果我们想实现int和double的比较,就可以这样写

 

template <class T,class M>  T  min(T a,M b)
{
    Return a<b?a:b;
}

然后T=int,M=double,就可以了。<>里面可以定义无数个你想要的类型(理论上),并在后面像普通的类型一样引用。

 

给初学者的小提示:在真正项目中经常会出现很多不认得的名字,比如

template <class _T_ptr,class _M_ptr>  _T_ptr   min(_T_ptr a,_M_ptr  b)
{
    Return a<b?a:b;
}

对于菜鸟来说好像看起来就厉害好多,其实掌握基本语法与结构,这就不是问题了。。要耐心去看)

 

 

那么,下面我们介绍第二种模板——类模板。格式如下,

template<class  形参名,class 形参名,…>   class 类名

{ 

   类的方法和属性

 };

 

 

下面接着上代码:

 

#inlcude <iostream>
template <class T> class Modle
{  private:
   T value;//这里T就相当于一个类型
   public:
   Modle(T t)
 {
    Value=t;
  }
   Void setValue(T v)
 {
   Value=v;
 }
   T getValue()
 {
   Return value;
 }

}
template <T>              //这里是在类模板外面声明成员函数的方法
void myClass<T>::show()
                      
{
  cout<<"value="<<value<<endl;
}
Modle <int> a(5), b(10); //这里注意类模板的用法,在类名后用<>加入你想要的类型cout<<"a.value:"<<a.getValue()<<endl;cout<<"b.value:"<<b.getValue()<<endl;
//测试char类型数据
Modle  ch('A');
cout<<"ch.value:"<<ch.getValue()<<endl;
ch.setValue('a');
cout<<"ch.value:"<<ch.getValue()<<endl;

 

 

 


我们使用的STL中经常会看到这种声明, Vector<int>  num;这回我们就应该理解了,stl里面的容器都是类模板,去查一下源代码,你会发现你可以理解它的原理的。

 

 

 

这里再贴一个提示:摘自觅思.澈的博客

对于template<class T>T g(T a, T b){}。当我们声明类对象为:A<int> a,语句调用a.g(2, 3.2)在编译时不会出错,但会有警告,因为在声明类对象的时

候已经将T转换为int类型,而第二个实参3.2把模板形参指定为double,在运行时,会对3.2进行强制类型转换为3。

当我们声明类的对象为:A<double> a,此时就不会有上述的警告,因为从int到double是自动类型转换。这是和函数模板不同的一点。

 

对于模板里的形参(就是这个尖括号里面的东西<class T>):有类型形参,非类型形参,模板形参三种。

上面举得例子都是类型形参,也就是<>里面声明是由class或typename完成的。

待进一步学习后,会把其他两种情况的理解分享出来~

 


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值