c++模板学习.docx_第1页
c++模板学习.docx_第2页
c++模板学习.docx_第3页
c++模板学习.docx_第4页
c++模板学习.docx_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1.模板的概念。我们已经学过重载(Overloading),对重载函数而言,C+的检查机制能通过函数参数的不同及所属类的不同。正确的调用重载函数。例如,为求两个数的最大值,我们定义MAX()函数需要对不同的数据类型分别定义不同重载(Overload)版本。/函数1.int max(int x,inty);return(xy)?x:y ;/函数2.float max(float x,floaty)return (xy)? x:y ;/函数3.double max(double x,doubley)return (cy)? x:y ;但如果在主函数中,我们分别定义了 char a,b; 那么在执行max(a,b);时 程序就会出错,因为我们没有定义char类型的重载版本。现在,我们再重新审视上述的max()函数,它们都具有同样的功能,即求两个数的最大值,能否只写一套代码解决这个问题呢?这样就会避免因重载函数定义不 全面而带来的调用错误。为解决上述问题C+引入模板机制,模板定义:模板就是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数, 从而实现了真正的代码可重用性。模版可以分为两类,一个是函数模版,另外一个是类模版。2.函数模板的写法函数模板的一般形式如下:Template 返回类型 函数名(形参表)/函数定义体 说明: template是一个声明模板的关键字,表示声明一个模板关键字class不能省略,如果类型形参多余一个 ,每个形参前都要加class 可以包含基本数据类型可以包含类类型.请看以下程序:/Test.cpp#includeusingstd:cout;usingstd:endl;/声明一个函数模版,用来比较输入的两个相同数据类型的参数的大小,class也可以被typename代替,/T可以被任何字母或者数字代替。templateT min(T x,T y)return(xy)?x:y;voidmain( )intn1=2,n2=10;doubled1=1.5,d2=5.6; cout较小整数:min(n1,n2)endl; cout较小实数:min(d1,d2)endl; system(PAUSE);程序运行结果:程序分析:main()函数中定义了两个整型变量n1 , n2 两个双精度类型变量d1 , d2然后调用min( n1, n2); 即实例化函数模板T min(T x, T y)其中为int型,求出n1,n2中的最小值同理调用min(d1,d2)时,求出d1,d2中的最小值3.类模板的写法定义一个类模板:Template class类名类定义;说明:其中,template是声明各模板的关键字,表示声明一个模板,模板参数可以是一个,也可以是多个。例如:定义一个类模板:/ ClassTemplate.h#ifndefClassTemplate_HH#defineClassTemplate_HHtemplateclassmyClassprivate: T1 I; T2 J;public: myClass(T1 a, T2 b);/Constructorvoidshow();/这是构造函数/注意这些格式templatemyClass:myClass(T1 a,T2 b):I(a),J(b)/这是void show();templatevoidmyClass:show() coutI=I, J=Jendl;#endif/ Test.cpp#include#includeClassTemplate.husingstd:cout;usingstd:endl;voidmain() myClass class1(3,5); class1.show(); myClass class2(3,a); class2.show(); myClass class3(2.9,10); class3.show(); system(PAUSE);最后结果显示:4.非类型模版参数一般来说,非类型模板参数可以是常整数(包括枚举)或者指向外部链接对象的指针。那么就是说,浮点数是不行的,指向内部链接对象的指针是不行的。templateclassStackPrivate: T elemsMAXSIZE;Int main() Stack int20Stack; Stack int40Stack;5.使用模板类型有时模板类型是一个容器或类,要使用该类型下的类型可以直接调用,以下是一个可打印STL中顺序和链的容器的模板函数template void print(T v)T:iterator itor;for (itor = v.begin(); itor != v.end(); +itor)cout *itor ;cout endl;void main(int argc, char *argv)list l;l.push_back(1);l.push_front(2);if(!l.empty()print(l);vector vec;vec.push_back(1);vec.push_back(6);if(!vec.empty()print(vec);打印结果类型推导的隐式类型转换在决定模板参数类型前,编译器执行下列隐式类型转换: 左值变换 修饰字转换 派生类到基类的转换 见C+ Primer(注2,P500)对此主题的完备讨论。简而言之,编译器削弱了某些类型属性,例如我们例子中的引用类型的左值属性。举例来说,编译器用值类型实例化函数模板,而不是用相应的引用类型。同样地,它用指针类型实例化函数模板,而不是相应的数组类型。它去除const修饰,绝不会用const类型实例化函数模板,总是用相应的非 const类型,不过对于指针来说,指针和 const 指针是不同的类型。底线是:自动模板参数推导包含类型转换,并且在编译器自动决定模板参数时某些类型属性将丢失。这些类型属性可以在使用显式函数模板参数申明时得以保留。6. 模板的特化如果我们打算给模板函数(类)的某个特定类型写一个函数,就需要用到模板的特化,比如我们打算用 long 类型调用 max 的时候,返回小的值(原谅我举了不恰当的例子):template / 这代表了下面是一个模板函数long max( long a, long b ) / 对于 vc 来说,这里的 是可以省略的 return a b ? b : a;实际上,所谓特化,就是代替编译器完成了对指定类型的特化工作,现代的模板库中,大量的使用了这个技巧。对于偏特化,则只针对模板类型中部分类型进行特化,如templateclass MyClass;templateclass MyCalss/偏特化7. 仿函数仿函数这个词经常会出现在模板库里(比如 STL),那么什么是仿函数呢?顾名思义:仿函数就是能像函数一样工作的东西,请原谅我用东西这样一个代词,下面我会慢慢解释。void dosome( int i )这个 dosome 是一个函数,我们可以这样来使用它: dosome(5);那么,有什么东西可以像这样工作么?答案1:重载了 () 操作符的对象,因此,这里需要明确两点:1仿函数不是函数,它是个类;2仿函数重载了()运算符,使得它的对你可以像函数那样子调用(代码的形式好像是在调用比如: struct DoSome void operator()( int i ); DoSome dosome;这里类(对 C+ 来说,struct 和类是相同的) 重载了 () 操作符,因此它的实例 dosome 可以这样用 dosome(5); 和上面的函数调用一模一样,不是么?所以 dosome 就是一个仿函数了。实际上还有答案2:函数指针指向的对象。 typedef void( *DoSomePtr )( int ); typedef void( DoSome )( int ); DoSomePtr *ptr=&func; DoSome& dosome=*ptr; dosome(5); / 这里又和函数调用一模一样了。当然,答案3 成员函数指针指向的成员函数就是意料之中的答案了。8. 仿函数的用处不管是对象还是函数指针等等,它们都是可以被作为参数传递,或者被作为变量保存的。因此我们就可以把一个仿函数传递给一个函数,由这个函数根据需要来调用这个仿函数(有点类似回调)。STL 模板库中,大量使用了这种技巧,来实现库的“灵活”。比如:for_each, 它的源代码大致如下:templatevoid for_each( Iterator begin, Iterato

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论