C中级培训教材.pdf

上传人:奔*** 文档编号:93501443 上传时间:2023-07-07 格式:PDF 页数:39 大小:4.21MB
返回 下载 相关 举报
C中级培训教材.pdf_第1页
第1页 / 共39页
C中级培训教材.pdf_第2页
第2页 / 共39页
点击查看更多>>
资源描述

《C中级培训教材.pdf》由会员分享,可在线阅读,更多相关《C中级培训教材.pdf(39页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、C+中级培训教材说明:、为便于储存与管理,各类培训教材均使用合订本。二、教材结构:各类培训教材由教材封面、前言、课程目录、单 门 课程教材与封底五部分构成。三、教材封面:1、封面颜色:教材封面为彩色,工作基本常识教材为深蓝色,技术基础知识教材为草绿色,管理基础知识教材为浅蓝色,营销基础知识教材为墨绿色。2、教材名称:使用“工作基本常识”“技术基础知识”“管理基础知识”“营销基础知识”,字体为隶书,黑 体,60号。3、其他标 识:员培训中心编 辑使用宋体、黑体、三号,位于教材名称下面;华为技术有限公司使用宋体、黑体、小二,位于底端;华为标识位于华为技术有限公司与员培训中心编 辑之间;右上角为保密

2、标 识,楷体,黑体,四号。四、教材封底:教材封底包含教材名称、华 为技术有限公司员培训中心与时 间、版本号,位于页面的右下角。五、前言:教材前言为各类培训的目的、课程门 类、特点、要紧内容的简介。六、课程目录:为各门课程排列顺序的目录,统编排页 码,便于学员查找。七、单门课程教材:各单门课程教材由课程封面、章节目录、章节内容、学习要求、思考题、参考资料与有关网站构成。1、课程封面:课程封面为彩色,课程名称之隶书、60号、黑体、黑色,左上角为课程编 码。2、章节目录:为宋体、小四、黑色3、章节内容:(1)标题:章节目分别以“第一章、第二章、第三章”“1.1、1.2、1.3”与“(1)(2)(3)

3、”来表示。章为宋体、小二、黑体,节为宋体、四号、黑体,目为宋体、小四、黑体。(2)文字:每四个小时的培训课程,字数操纵在1 0 0 0 0 2 0 0 0 0 字之间。教材文字通常为宋体、小四、黑色,行间距为一行半。(3)内容:章节内容要有完整的理论体系,不能成为授课胶片的翻版。4、学习要求:每章标题下面为本章的学习要 求,以明确本章要掌握的要点。文字为楷体、小四。5、思考题:每章最后要有思考题,以便帮助学员复习、思考。6、参考资料与有关网站:有参考资料与有关网站的要附在课程后面,以便帮助学员查阅。内部资料,注意保密C+中级培训效 程员培训中心 编辑2005年6月 VI.0华为技术华为技术有限

4、公司前 言C+语言中级教材讲授C+语言的运用技术,包 含:类、对象之间的关系、对象的存储与布局、运算符重载、智能指针、仿函数、泛型编程,C+模式设 计基本思想。NE002009cVl.01业 务与软件C+语言项目C+进阶三录第 一 章类、接口.71.1 Handle-Body与接口、抽象接口.71.2 多继承、与菱形缺陷、th is跳转等.131.3 C+多态的两种多态形式与区别.18第 二 章 重载.182.1 函数重载.192.2 运算符重载.20第 三 章 模 板.293.1 模块函数.293.2 模块 类.313.3 STL标准模板库.34附录:参考资料.39前后我们在C+基础 课程中

5、已经熟悉了C+的些基本概念,明白了什么是类什么是对象。也熟悉了继承、封装、多态等C+面向对象的基本特征,本课程要紧是更进步探讨一下C+些基本模型的应用,加深对概念的懂得,由于课程时 间有 限,C+,模型与内容又如此之多,对任何一个模型都无法深入进去,因此只能泛泛而谈。第一章 类、接口学习要求:1、熟 悉类的继承、封 装 等 概 念 之间的 关 系2、熟悉什 么 是 接 口,什 么 是 虚 函 数,它 有 什 么样的特 点。学 会 使 用 接 口编程的思想本章节要紧介绍C+中的类、接 口。类,包 涵 了 一组数 据 与 一组基 于 数 据 上 的 组方 法。它 描 述 了 一 个对象 的 属 性

6、、状态与 行为;接 口,它 只 是 描 述 了 一 个对象的简 单的行为。有关类的基本概念:Class namesClass membersMember FunctionsStatic Member FunctionsUnionsC+Bit FieldsNested Class DeclarationsType Names in Class ScopeMultiple Base ClassesVirtual FunctionsAbstract ClassesControlling Access to Class Membersprivate Membersprotected Memberspu

7、blic MembersAccess Specifiers for Base Classes,priavte,public protectedFriendsConstructorsDestructorsConversion Functionsthe new operator and the delete operatorCopying Constructor FunctionsInterface1.1 Handle-Body与接口、抽象接口在C+中封装的概念是把个对象的外观接口同实际工作方式(实 现)分离开来,但是C+的封装是不完全的,编 译器务必明白个对象的所有部分的声明,以便创建与管理它。

8、我们能够想象一种只需声明一个对象的公共接口部分的编程语言,而将私有的实 现部分隐藏起来。C+在编 译期间要尽可能多地做静态 类型检 查。这意味着尽早捕获 错 误,也意味着程序具有更高的效率。然而这 对私有的实 现部分来说带来两个影响:是即使程序员不能轻易地访 问 实 现部分,但他能够看到它;是造成一些不必要的重复编 译。然而C+并没有将这个原则应用到二进制层次上,这是由于C+的类既是描述了个接口同时也描述了实 现的过程,示比如下:class CMyString(private:const int m_cch;char*m_psz;public:CMyString(const char*psz)

9、;CMyString。;int Length()const;int Index(const char*psz)const;CMyStirng对外过多的暴露了内存布局实 现的细 节,这些信息过度的依靠于这些成员变量的大小与顺序,从而导致了客户过度依靠于可执行代码之间的二进制耦合关系,这样的接口不利于跨语言跨平台的软件开发与移植。1.1.1 HandleBody 模式解决这个问题的技术有的时候叫句柄类(handle c la sses)或者叫CheshireCat 1 o有关实 现的任何东西都消失了,只剩个单一的指针“m_pThis”。该指针指向一个结构,该结构的定义与其所有的成员函数的定义样 岀

10、 现在实 现文件中。这样,只要接口部分不改变,头文件就不需变 动。而实现部分能够按需要任意更动,完成后只要对 实 现文件进行重新编 译,然后再连接到项目中。这里有这 项技术的简单例子。头文件中只包含公共的接口与一个简 单的没有完全指定的类指针。class CMyStringHandle(private:class CMyString;CMyString*m_pThis;public:CMyStringHandle(const char*psz);CMyStringHandle();int Length()const;int Index(const char*psz)const;卜CMyStri

11、ngHandle:CMyStringHandle(const char*psz):m_pThis(new CMyString(psz);()CMyStringHandle:CMyStringHandleQdelete m_pThis;int CMyStringHandle:Length()return m_pThis-Length();)int CMyStringHandle:Index(const char*psz)(return m_pThis-Index(psz);)这是所有客户程序员都能看到的。这行class CMyString;是个没有完全指定的类型说明或者类声明(个类的定义包含类的

12、主体)。它告诉编译器,C heshire是个结构的名字,但没有提供有关该结构的任何东西。这 对 产生个指向结构的指针来说已经足够了。但我们在提供个结构的主体部分之前不能创建一个对象。在这种技术里,包含具体实 现的结构主体被隐藏在实 现文件中。在设计模式中,这就叫做Handle-Body模式,Handle-Body只含有一个实体指针,服务的数据成员永远被封闭在服务系统中。Handle-Body模式如下:classHandlem_pThis图1 Handle-Body模式(句柄类做为接口)Handle-Body的布局结构永远不可能随着实现类数据成员的加入或者者删除或者者修改而导致Handle-Bo

13、dy的修改,即Handle-Body协 议不依靠于C+实 现 类的任何细 节。这就有效的对用户的编译器隐藏了这些斜街,用户在使用对这项技术时候,Handle-Body接口成了它唯一的入口。然而Handle-Body模式也有自己的弱点:1、接类务必把每一个方法调用显示的传递给实现类,这在个只有一个构造与一个析构的类来说显然不构成负担,但是假如一个庞大的类库,它有上百上千个方法时候,光是编写这些方法传递就有可能非常冗长,这也增加了出错的可能性。2、关于关注于性能的应用每个方法都得有两层的函数调用,嵌套的开销也不理想3、由于句柄的存在依然存在编译连接器兼容性问题。接口与实现分离的Handle-Bod

14、y。1.1.2抽象接口使用了“接口与实现的分离”技术的Handle-Body解决了编译器/链接器的大部分问题,而C+面向对象编程中的抽象接口同样是运用了“接口与实现分离”的思想,而使用抽象接口关于解决这类问题是个极其完美的解决方案。1、抽象接口的语言描述:class IMyString(virtual int Length()const=0;这表示是个纯虚函数,具有纯虚函数的接口virtual int Index(const char*psz)const=0;卜2、抽象接口的内存结构:图 2 抽象接口的内存布局3、抽象接口的实现代码:接口:class IMyString(virtual int

15、 Length()const=0;这表示是个纯虚函数,具有纯虚函数的接口virtual int Index(const char*psz)const=0;);实现:class CMyString:public IMyString(private:const int m_cch;char*m_psz;public:CMyString(const char*psz);virtual-CMyString();int Length()const;int Index(const char*psz)const;从上面使用抽象接口的实例来看,抽象接口解决了Handle-Body所遗留下来的全部缺陷。抽象接口

16、的个典型应用:抽象厂(AbstractFactroy)图3抽象工厂模式1.2多继承与菱形缺陷、th is跳转等多重继承是C+语言独有的继承方式,其它几乎所有语言都秉承了单继承的思想。这是由于多重继承致命的缺陷导致的:1.2.1 菱形缺陷当继承基类 时,在派生类中就获得了基类所有的数据成员副本。假如类B从A1与A2两个类多重继承而来,这样B类就包含Al、A2类的数据成员副本。考虑假如Al、A2都从某基类派 生,该基类称之B a se,现在继承关系如下:图4菱形继承关系我们C+语言来描述这种继承关系:c l a s s B a s e .;c l a s s A l :p u b l i c B

17、a s e .;c l a s s A 2 :p u b l i c B a s e .;c l a s s B :p u b l i c A l,p u b l i c A 2 .;那么A l、A 2都具有B a s e的副本。这样B就包含了B a s e的两个副本,副本发生了重叠,不但增加了存储空间,同 时也引入了二义性。这就是菱形缺陷,菱形缺陷时间是两个缺陷:1、子对象重叠2,向上映射的二义性。菱形缺陷的其中一种解决办法将在C+世界里最广泛的使用虚拟继承解决菱形缺陷的应用便是标准C+的输入/输出 i os t r e a m;basic iosvirtual virtualba sic

18、ostream basicjostreamiostream图5标准C+的输入/输出1.2.2 多重接口与方法名冲突问 题(Siamese twins)对 继承而来的虚函数改写很容易,但是假如是在改写个“在两个基类都有相同原型”的虚函数情况就不那么容易了。提出问题:假设汽车最大速度的接口为IC ar,潜艇最大速度的接口为!B oat,有一个两栖类的交通工具它能够奔跑在马路上,也能够航行在大海中,那么它就同时拥有ICar、IBoat两种交通工具的最大速度特性,我们定义它的接口为ICarBoat;class ICar(virtual int GetMaxSpeed()=0;卜class IBoat(

19、virtual int GetMaxSpeed()=0;);我们先对ICarBoat的接口做个尝 试:class CCarBoat(virtual int GetMaxSpeed();既完成ICar的GetMaxSpeed()接 口 方法又完成IBoat的接口方法?显然不能够解决问 题:显然上面这个尝 试根本就无法成功,只用个实 现方法,怎么能够求出这个ICarBoat交通工具奔跑在马路上的最高时速,同时也能够求出航行在大海上的最大航行速度呢。上面这问题矛盾就在-个方法,却需要两个答案。看来ICarBoat要返回两个答案就务必有两个方法了,我们假设个方法是求在陆地上奔跑的速度,名称之GetCa

20、rMaxSpeed ;另个方法是求在大海上航行的最大速度,名称之GetBoatMaxSpeed ;那这两个方法又怎么与GetMaxSpeed 接口方法联系起来呢;幸运的是,我们找到熟悉决办法,而且解决办法有很多种,下面介绍一下继承法。class IXCar:public IC ar(virtual int GetMaxSpeed()(GetCarMaxSpeed();)virtual int GetCarMaxSpeed()=0;);class IXBoat:public IBoat(virtual int GetMaxSpeed()GetBoatMaxSpeed();virtual int

21、GetBoatMaxSpeed()=0;);classCCarBoat:public IXCar,public IXBoatvirtual int GetCarMaxSpeed()virtual int GetBoatMaxSpeed()图6 多重接口与方法名冲突问题1.2.3 this 跳转this跳转是指的“对象同一性”问题。在单继承的世界内,不管继承关系怎么复杂,针关于同一对象,不管它的子类或者者父类的this指针永远相等。即假如有下面的模型:AB图7 B 从A继承的关系图那么关于个已经 实例化B类的对象 b O b j e c t,永远有(B*)&b O b j e c t=(A*)&

22、b O b j e c t 成立。但是在多继承的世界内,上面的等式就不能恒成立,对象的同一性受到了挑战。特别的是,在多继承世界内假如图四的菱形关系存在情况下,假如关于已经 实例化B类的对象b O b j e c t;(B a s e*)(A l*)&b O b j e c t !=(B a s e*)(A 2*)&b O b j e c t 成立,当这种情况发生的时候我们就只能特殊处理了。这种情况在C O M应用中处 处都会发生。1.3 C+多态的两种多态形式与区别C+有两种多态多态形式:1、编 译 时刻多态,编 译 时刻多态依靠函数重载或者者模板实现2、运行时刻多态。运行时刻多态依靠需函数虚

23、接口实现第二章 重载学习要求:1、熟悉什么是函数重载,什么是运算符重载2、学会运用智能指针,仿函数在 C+的世界里,有两种重载:函数重载与运算符重载,函数重载就使用使用参数匹配的原则,进行重载的,它是种编 译 时刻的多态。而运算符重载,使使用改写或者者说重新定义C+的内嵌运算符的方法。有关重载的基本概念:Overloaded FunctionsOverloaded OperatorsDeclaration MatchingArgument MatchingArgument Types MatchingArgument Counts MatchingC+Unary OperatorsBinary

24、 OperatorsSmart PointerFunction objects1.1 函数重载函数重载方法是在当前范围内选 择个最佳匹配的函数声明供调用该方法者使用。假如一个适合的函数被找到后,这个函数将会被调用,在这里“适合的”是指按下列顺序匹配的符合下面条件的:1、个精确匹配的函数被找到2、一个参数只有细微的差别,几乎能够忽略不计的。3、象类似通过子类向父类转化达到参数匹配的4、通过正常转化函数进行类型转 换,能够达到参数匹配到的。5、通过用户自定义的转化函数(如转化运算符或者者构造函数)达到参数匹配的6、参数是使用省略符号函数重载的方法基本上有:1、根据函数参数数据类型的不一致进行的重载

25、;2、根据参数个数的不一致进行的重载;3、缺省参数上的重载我们在这里把缺省参数也称之一种函数重载,实际上它并不是严格意义上的重载。在使用缺省参数时 务必记住两条规 则。第一,只有参数列表的后部参数但是缺省的,也就是说,我们不能够在个缺省参数后面又跟个非缺省的参数。第二,一旦我们开始使用缺省参数,那么这个参数后面的所有参数都务必是缺省的。第三,缺省参数只能放在函数声明中。第四,缺省参数能够 让声明的参数没有标 识符。4、返回值重载特别注意,在C+中并没有根据返回返回值的不一致进行重载的,即我们不能定义 这 样的函数:v oid f ();int f ();在C+中这 样的函数声明方法是被禁止的,

26、但是我们有的时候间可能又需要这样的重载方法,我们又怎么实 现呢,事实上很简 单,j ia ng 函数的参数进行扩展,将这个函数返回值的数据类型,做为扩展参数的数据类型来。如下:v oid f (v oid);v oid f (int);如今这个例子中的参数列表的数据,只在编 译 时刻起到分练函数的作用,在运行时刻并不起到传 值作用,模板中经常都应用到了这种方法。1.2 运算符重载你能够重新定义C+绝大多数内嵌运算符的实现方法与功能,这些重定义的或者者说重载的运算符,有可能全局作用的,也有可能作用在类基础之上的,运算符重载的实现可能以类的成员函数的形式出现,也有可能以全局性的函数的身份出现。在

27、C+中重载运算符的名字为ope ra tor%在这里 x 是个可重载的运算符,如:重载加法运算符,你需要定义个名为ope ra tor卡的函数,然后实现他,其它的类似定义就能够了,比如:C la ss comple x /v e ry simplif ie d comple x(d ou b le re,im;pu b lic:comple x (d ou b le r,d ou b le i):re (r),im(i);comple x ope ra tor+(comple x);comple x ope ra tor*(comple x);;定义了 comple x这个复数的个简单的实现概

28、念模型。个复数是由一对d ou b le类型的数据构成,并定义了这个复数的两个方法,加法运算comple x:ope ra rtor+()与乘法运算comple x:ope ra tor*(),现在我们就能够实现下面的复数表达式了:v oid f()(comple x a =comple x(1 ,3.1);comple x b =comple x(1.2,2);comple x c=b;a =b +c;b =b +c*a;c=a *b +comple x (1 ,2);)1.3.1 C+可重载的与C+不可重载的运算符可重载运算符表:Operator NameTypeOperatorNameT

29、ype,C ommaB ina ry-*P ointe r-to-me mb e rse le ctionB ina ry!L og ica l N O TU na ry/D iv isionB ina ry!=I ne qu a lityB ina ry/=D iv ision/a ssig nme ntB ina ry%M od u lu sB ina ryL e ss tha nB ina ry%=M od u lu s/a ssig nme ntB ina ryL e f t shif tB ina ry&B itw ise A N DB ina ry=L e f tshif t/a

30、ssig nme ntB ina ry&A d d re ss-ofU na ryG re a te r tha nB ina ry*M u ltiplica tionB ina ry=G re a te r tha n ore qu a l toB ina ry*P ointe r d e re f e re nceU na ryR ig ht shif tB ina ry*二M u itiplica tion/a ssig nB ina ry=R ig htshif t/a ssig nme ntB ina ry+A d d itionB ina ry A rra y su b scrip

31、t+U na ry P lu sU na ryE x clu siv e O RB ina ry+I ncre me nt1U na ry 二E x clu siv eO R/a ssig nme ntB ina ry+=A d d ition/a ssig nme ntB ina ry1B itw ise inclu siv e O R B ina ry-S u b tra ctionB ina ry1=B itw ise inclu siv eO R/a ssig nme ntB ina ry-U na ry ne g a tionU na ryIIL og ica l O RB ina

32、ry-D e cre me nt1U na ryO ne s comple me ntU na ry-=S u b tra ction/a ssig nB ina ryd e le ted e le te-M e mb e r se le ctionB ina ryne w不可重载运算符表:O pe ra torN a meM e mb e r se le ction P ointe r-to-me mb e r se le ction S cope re solu tion?:C ond itiona l#P re proce ssor sy mb ol#P re proce ssor sy

33、 mb ol在上面可重载的运算符能够看出运算符重载共分为两类:一元运算符重载与二元运算符重载一元运算符重载:在声明一个类的非静态的一元运算符重载函数时,你务必声明的形式如下:ret-type operatorop()(1)在这里 ret-typ e是 指 返 回 数 据 类 型o p是 指 一 元 运 算 符在声明一个全局的一元运算符重载函数时,你务必声明的形式日下:ret-type operatorop(arg)(2)在这里 ret-typ e与op与 上 面 的 意 思 样,arg是 指 这 个 运 算 符 所 作 用的 数 据 类 型二元运算符重载:在声明一个类的非静态的二元运算符重载函

34、数时,你务必声明的形式如下:ret-type operatorop(3)(3)式与二式基本相同a rg能 够 是任何个在声明一个全局的二元运算符重载函数时,你务必声明的形式日下:ret-type operatoropkargl,arg公(4)在这里 ret-typ e与op与 上 面 的 意 思 样,argl,arg2,是 指 这 个 运 算符 所 作 用 两 个 数 据 类 型1.3.2几类特殊的运算符重载1、类型转 换运算符所有的数据类型均能够定义构造函数,包含系统定义的数据类型与用户自定义的数据类型,如:c l a s s C S t r i n g(operator LPCSTRQ c

35、onst;);应用:C S t r i n g s t r =1 2 3 4 5”;L P C S T R I p s z =s t r;此处会进行L P C S T R运算这只是一个简 单的应用的示例,事实上有的时候间类型转 换具有无比强大的功能。我曾经就是用类型装换运算符重载解决一个跨平台通信的问题。2、b o o l运算符重载i n t、f l o a t,b o o l等运算符也是能够重载的,比如重载b o o l运算符,但是重载运算符b o o l时候,需要注意有很多烦 恼与臆想不到的东西t e m p l a t e c l a s s t e s t b o o l(operat

36、or bool()const throw()(return m_ pT!=0;)p r i v a t e:T*m_pT;下面结果均通过编译t e s t b o o l s p l;t e s t b o o K s t d:s t r i n g s p 2;if(spl=sp2)if(spl!=sp2)bool b=splint I=spl*10;从上面能够看得出b o o l的表现已经 远 远超过b o o l本身了,因此建议大家不要轻易对b o o l进行重载操作。3、地址运算符重载在D C O M应用中,我们有一个重载运算符的例子:S T D A P I C o C r e a t

37、 e l n s t a n c e(R E F C L S I D rclsid,L P U N K N O W N pUnkOuter,D W O R D dwClsContext,R E F I I D riid,LPVOID*ppv);我们看最后个参数LPVOID指针的指针,这里是个输出参数,返回个接口的指针。通常情况下我们 应用如下IUnknown*pUn;C o C r e a te I n s ta n c e(,(void*)&pUn);(5)然而我们也能够 这 样写:IUnknown*pUn;CComPtr comPtr(pUn);C o C re a te In s ta

38、n c e(v o id *)&comPtr);(6)之因此能够 这么写这是由于CComPtr重载了 运算符,如下:template class CComPtr(public:CComPtr(T*Ip)(if(p=lp)!=NULL)p-AddRef();T*operator&()ATLASSERT(p=NULL);return&p;private:T*p;);&comPtr实 际上是得到了通常的情况下,我们并不能对pUn的 地 址,因 此(5)式 与(6)式事实上传入的参数是样当都是传入了 pU n的地址。尽管我们能够 对运算符进行重载,但通常情况下我们并不是很提倡这种操作,这是由于:A、暴

39、露了封装对象的地址,如上面CComPtr对pUn的封装事实上不起任何作用,任何时候我都能够直接访 问与修改pUn指针,这就意味着所有权的完全丧失,封装不起任何意义B、关 于 unary operatorfe的重载使得重载 对方永远无法与STL容器进行任何融合,甚至无法参与任何泛型编程。个对象的地址是个对象最基本的概念,在通常情况下,我们并不提倡,也请大家慎用地址运算符的重载。4、指针运算符重载指针运算符,有一个及其特殊且及其重要的机制:当你对某个型别 实施。perator-而这个型别并非原生指针 时候:编 译器会从这个型别中找出用户自定义的 operator-),并实施后,编 译器将继续 对

40、这个operator 返回的结果实施 operator-)直到找到个原生指针。这种机制导致了一个特有的技术:(pre and post function calls),“前调用”及后调用技术。应用如下:class CallDoSomething(public:void DoCall()(TRACE(DoCalln););templateclass CalllnMutiThreadclass LockProxy(public:LockProxy(T*pT):m_pT(pT)|TRACE(Lock n);)LockProxy()(TRACE(UnLock n);)T*operator-()(ret

41、urn m_pT;)private:T*m_pT;);public:CallInMutiThread(T*pT):m_pT(pT)()LockProxy operator-()(return LockProxy(m_pT);)private:T*m_pT;);上 面 CallDoSomething是函数调用,假设 这个类原先是在单 线程中运行的,但是现在已经移植到了多环境中,因此我们就增加了 CalllnMutiThread对 原始类进行配接使之习惯与多线程环境,调用过程如下:CallDoSomething DoSomthing;CallInMutiThread MutiThread(&DoS

42、omthing);MutiThread-DoCall();调用结果如下:L o c kD o C a l lU n L o c k从上面能够看出在调用CallDoSomething的成员函数D oC all之前调用了 Lock方法,在调用结束后有调用了UnLock。这就是所谓的“前调用”与“后调用”,事实上并不仅 仅是多线程问题能够使用此办法,所有的“前调用“与 后调用”模式均可由此解。重载“”运算符,同时引出了智能指针的概念,参见下页。5、括号运算符重载语法特征:primary-expression(expression-listo)括号运算符是个 同“”运算符样也是个及其重要的运算符在M

43、SDN上说括号运算符是个二元运算符,我觉得这个说法是完全错 误的,在所有C+运算符重载中,括号运算符,应 该是唯一没有规定参数元的个数的。它的参数能够从0个 到N个。示例:class Point(public:Point()_x=_y=0;Point&operator()(int dx,int dy)_x+=dx;_y+=dy;return*tnis;private:int _x,_y;);调用如下:Point pt;pt(3,2);从上面能够看出,括号运算符,调用形式如下:object(parameter l i s t);看起来与函数的形式是完全一样的:functionparameter

44、l i s t);因此根据这特点我们称之为仿函数。第三章 模板学习要求:1、熟悉什么是模板2、学会运用模板函数,模版类与S T L模 板(t e m p l a t e s),与以模版为基础的泛型编程与泛型模式,是当今C+中最活跃的项编程技术,模版的第一个革命性的应用就是S t a n d a r d T e m p l a t e L i b r a (简称S T L)。S T L 将t e m p l a t e s 技术广泛应用于S T L 容器与S T L 算法上,在这领域t e m p l a t e技术 发 挥到了极致。本章介绍C+t e m p l a t e s 的基本概念与语

45、言特性1.1 认 识模板1、模板的基本语法是:template declaration这个template描述了一个参数化的类(模板类)或者者是个参数化的函数(模板函数),这个模板参数列表是用逗号分隔的类型列表(在这个表单忠使用class或者者 是 typename来标 识 这个数据类型)。在某些情况下这个模板体内可能不存在任何的数据类型。declaration域务必是个函数或者者类的声明。1.4 模板函数语法定义:t e m pl a t e f u nc t i on-na m e(pa r a m e t e r l i s t)()比如:t e m pl a t e i nl i ne

46、 T c ons t&m a x (T c ons t f i.a,T c ons t&b)(/i f a b t h e n u s e b e l s e u s e ar e t u r n a b?b:a;)调用形式:1 :通过调用的参数来识别模板的各参数类型MAX(4,4.2);/OK,but type of first argument defines return type2,明确指定参数的类型:MAX(4,4.2);/OK在我们的例子中这个参数列表是typename T,事实上在这里typename是能够用 c la s s 替换的,typenam e是在C+演化过程中逐步形成

47、的,而class是个历史性的概念,typename表达了一个 比 c la s s 更抽象意义上的概念。有如下定义如:class typenamedef(typedef int INT_TYPE;);假如这样表达是正确的:templateclass testtypename:public typenamedef(public:typename T:INT_TYPE;INT.TYPE mjnt;);但是假如把 此处的typename换 成 class就会报错1.4.1 重载模板函数(Overloading Function Templates)与普通的函数一样,模板函数也能够被重载,也就是说对象

48、同的函数名,你能够具有不一致的函数定义,在调用的时候再由C+编译器决定,那一个候选函数更有资格被匹配调用。下面这个简单的例子说明了重载模板函数的方法与过程:/maximum of two int valuesinline int const&max(int const&a,int const&b)(return ab?b:a;)/maximum of two values of any typetemplate inline T const&max(T const&a,T const&b)return ab?b:a;/maximum of three values of any typetem

49、plate inline T const&max(T const&a,T const&b,T const&c)return max(max(a,b),c);)int main():max(7,42,68);/calls the template for three arguments:max(7.0,42.0);/calls max(by argument deduction):max(a;b);/calls max(by argument deduction):max(7,42);/calls the nontemplate for two ints:max(7,42);/calls max

50、(by argument deduction):max(7,42);/calls max(no argument deduction)上面这个例子也说明了普通的函数与模板函数能够拥有同一个名字,而且能够被初始化为同一类型,如:max(7,42)调用匹配非模板函数也匹配模板函数。1.5模板类基本的语法定义:t e m pl a t e c l a s s c l a s s-na m e();具有缺省参数的模板定义形式t e m pl a t e c l a s s c l a s s-na m e();在模板中用到了大量非习惯性思维方法,大家在学习模板之前需要熟悉这些模板设计的思维方法:申明并

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com