华为内部C中级培训教材.pdf

上传人:文*** 文档编号:88947571 上传时间:2023-05-04 格式:PDF 页数:52 大小:5.04MB
返回 下载 相关 举报
华为内部C中级培训教材.pdf_第1页
第1页 / 共52页
华为内部C中级培训教材.pdf_第2页
第2页 / 共52页
点击查看更多>>
资源描述

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

1、内部资料,注意保密C+中 级 培 训教 程员工培训中心 编 辑2 0 0 5 年6 月 V I.0华为技术有限公司前 言华为技术C+语言中级教材讲授C+语言的运用技术,包括:类、对象之间的关系、对象的存储与布局、运算符重载、智能指针、仿函数、泛型编程,C+模式设计基本思想。说明:一、为便于保存和管理,各类培训教材均采用合订本。二、教材结构:各类培训教材由教材封面、前言、课程目录、单门课程教材和封底五部分构成。三、教材封面:1、封面颜色:教材封面为彩色,工作基本常识教材为深蓝色,技术基础知识教材为草绿色,管理基础知识教材为浅蓝色,营销基础知识教材为墨绿色。2、教材名称:采 用“工作基本常识”“技

2、术基础知识”“管理基础知识”“营销基础知识”,字体为隶书,黑体,6 0 号。3、其他标识:员工培训中心编辑采用宋体、黑体、三号,位于教材名称下面;华为技术有限公司采用宋体、黑体、小二,位于底端;华为标识位于华为技术有限公司和员工培训中心编辑之间;右上角为保密标识,楷体,黑体,四号。四、教材封底:教材封底包括教材名称、华为技术有限公司员工培训中心和时间、版本号,位于页面的右下角。五、前言:教材前言为各类培训的目的、课程门类、特点、主要内容的简介。六、课程目录:为各门课程排列顺序的目录,统一编排页码,便于学员查找。七、单门课程教材;各单门课程教材由课程封面、章节目录、章节内容、学习要求、思考题、参

3、考资料和相关网站组成。1、课程封面:课程封面为彩色,课程名称为隶书、6 0 号、黑体、黑色,左上角为课程编码。2、章节目录:为宋体、小四、黑色3、章节内容:(1)标题:章节目分别以“第一章、第二章、第三章”“1.1、1.2、1.3”和“(1)(2)(3)”来表示。章为宋体、小二、黑体,节为宋体、四号、黑体,目为宋体、小四、黑体。(2)文字:每四个小时的培训课程,字数控制在1 0 0 0 0 2 0 0 0 0 字之间。教材文字一般为宋体、小四、黑色,行间距为一行半。(3)内容:章节内容要有完整的理论体系,不能成为授课胶片的翻版。4、学习要求:每章标题下面为本章的学习要求,以明确本章要掌握的要点

4、。文字为楷体、小四。5、思考题:每章最后要有思考题,以便帮助学员复习、思考。6、参考资料和相关网站:有参考资料和相关网站的要附在课程后面,以便帮助学员查阅。N E 0 0 2 0 0 9 c V l.01业务与软件C+语言项目C+进 阶录第 一 章 类、接口 .71.1 Handle-Body 与 接 口、抽 象 接口 .71.2 多继承、与菱形缺陷、t h i s 跳 转等.131.3 C+多态的两种多态形式和区别.18第 二 章 重载.182.1 函 数 重载.192.2 运 算 符 重载.20第 三 章 模板.293.1 模块函数.293.2 模块类.313.3 STL标准模板库.34附

5、录:参考资料.39ISC基本知识附录:名词解释、,一、一前S我们在C+基础课程中已经了解了C+的一些基本概念,知道了什么是类什么是对象。也了解了继承、封装、多态等C+面向对象的基本特征,本课程主要是更进一步探讨一下C+一些基本模型的应用,加深对概念的理解,由于课程时间有限,C+,模型和内容又如此之多,对任何一个模型都无法深入进去,所以只能泛泛而谈。第一章 类、接口学习要求:1、了解类的继承、封装等概念之间的关系2、了解什么是接口,什么是虚函数,它有什么样的特点。学会使用接口编程的思想本章节主要介绍C+中的类、接口。类,包涵了一组数据和一组基于数据上的一组方法。它描述了一个对象的属性、状态和行为

6、;接口,它只是描述了一个对象的简单的行为。有关类的基本概念:Class namesClass membersMember FunctionsStatic Member FunctionsUnionsC+Bit FieldsNested Class DeclarationsType Names in Class ScopeMultiple Base ClassesVirtual Functions101SC基本知识 附录:名 词 解 释Abstract ClassesControlling Access to Class Membersprivate Membersprotected Membe

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

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

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

10、数的定义一样出现在实现文件中。这样,只要接口部分不改变,头文件就不需变动。而实现部分可以按需要任意更动,完成后只要对实现文件进行重新编译,然后再连接到项目中。121SC基本知识 附录:名词解释这里有这项技术的简单例子。头文件中只包含公共的接口和一个简单的没有完全指定的类指针。class CMyStringHandle(private:class CMyString;CMyString*m_pThis;public:CMyStringHandle(const char*psz);CMyStringHandle();int Length()const;int Index(const char*ps

11、z)const;);CMyStringHandle:CMyStringHandle(const char*psz):m_pThis(new CMyString(psz);()CMyStringHandle:CMyStringHandle()(delete m_pThis;)int CMyStringHandle:Length()(return m_pThis-Length();)int CMyStringHandle:Index(const char*psz)131SC基本知识 附录:名 词 解 释return m_pThis-Index(psz);这是所有客户程序员都能看到的。这行class

12、 CMyString;是一个没有完全指定的类型说明或类声明(一个类的定义包含类的主体)。它告诉编译器,Cheshire是一个结构的名字,但没有提供有关该结构的任何东西。这对产生一个指向结构的指针来说已经足够了。但我们在提供一个结构的主体部分之前不能创建一个对象。在这种技术里,包含具体实现的结构主体被隐藏在实现文件中。在设计模式中,这就叫做Handle-Body模式,Han祖e-Body只含有一个实体指针,服务的数据成员永远被封闭在服务系统中。Handle-Body模式如下:classHandlem_pThis图1 Handle-Body模 式(句柄类做为接口)Handle-Body的布局结构永

13、远不会随着实现类数据成员的加入或者删除或者修改而导致Handle-Body的修改,即Handle-Body协议不依赖于C+实现类的任何细节。这就有效的对用户的编译器隐藏了这些斜街,用户在使用对这项技术时候,Handle-Body接口成了它唯一的入口。141SC基本知识 附录:名词解释然而H a n d l e-B o d y模式也有自己的弱点:1、接口类必须把每一个方法调用显示的传递给实现类,这在一个只有一个构造和一个析构的类来说显然不构成负担,但是如果一个庞大的类库,它有上百上千个方法时候,光是编写这些方法传递就有可能非常冗长,这也增加了出错的可能性。2、对于关注于性能的应用每一个方法都得有

14、两层的函数调用,嵌套的开销也不理想3、由于句柄的存在依然存在编译连接器兼容性问题。接口和实现分离的Handle-Body。1.1.2抽象接口使用了“接口与实现的分离”技术的H a n d l e-B o d y解决了编译器/链接器的大部分问题,而C+面向对象编程中的抽象接口同样是运用了“接口与实现分离”的思想,而采用抽象接口对于解决这类问题是一个极其完美的解决方案。1、抽象接口的语言描述:class IMyString(virtual int Length()const=0;这表示是一个纯虚函数,具有纯虚函数的接口virtual int Index(const char*psz)const=0

15、;;2、抽象接口的内存结构:151SC基本知识附录:名词解释图 2 抽象接口的内存布局3、抽象接口的实现代码:接口:class IMyString(virtual int 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);161SC基本知识 附录:名 词 解 释virtual-CM

16、yString();int Length()const;int Index(const char*psz)const;)从上面采用抽象接口的实例来看,抽象接口解决了 Handle-Body所遗留下来的全部缺陷。抽象接口的一个典型应用:抽象工 J(AbstractFactroy)图 3抽象工厂模式1.2 多继承与菱形缺陷、this跳转等多重继承是C+语言独有的继承方式,其它儿乎所有语言都秉承了单一继承的思想。这是因为多重继承致命的缺陷导致的:1.2.1 菱形缺陷171SC基本知识 附录:名词解释当继承基类时,在派生类中就获得了基类所有的数据成员副本。假如类B从A 1和A 2两个类多重继承而来,这

17、样B类就包含A l、A 2类的数据成员副本。考虑如果A l、A 2都从某基类派生,该基类称为B a s e,现在继承关系如下:BaseB图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 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的两个副本,副本发生了重叠,不但增加了存储空间,同时也引入了

18、二义性。这就是菱形缺陷,菱形缺陷时间是两个缺陷:1、子对象重叠2、向上映射的二义性。菱形缺陷的其中一种解决办法将181SC基本知识 附录:名词解释在C+世界里最广泛的使用虚拟继承解决菱形缺陷的应用便是标准C+的输入/输出iostream;图 5 标准C+的输入/输出1.2.2多重接口与方法名冲突问题(Siamese twins)对继承而来的虚函数改写很容易,但是如果是在改写一个“在两个基类都有相同原型”的虚函数情况就不那么容易了。提出问题:假设汽车最大速度的接口为IC a r,潜艇最大速度的接口为IB o at,有一个两栖类的交通工具它可以奔跑在马路上,也可以航行在大海中,那么它就同时拥有IC

19、ar、IBoat两种交通工具的最大速度特性,我们定义它的接口 为 ICarBoat;class ICar|virtual int GetMaxSpeed()=0;);class IB oat(virtual int GetMaxSpeed()=0;191SC基本知识 附录:名词解释);我们先对ICarBoat的接口做一个尝试:class CCarBoat(virtual int GetMaxSpeed();既完成ICar的GetMaxSpeed()接口方法又/完成IBoat的接口方法?显然不能够;解决问题:显然上面这个尝试根本就无法成功,只用一个实现方法,怎么能够求出这个ICarBoat交通工

20、具奔跑在马路上的最高时速,同时也能够求出航行在大海上的最大航行速度呢。上面这一问题矛盾就在一一个方法,却需要两个答案。看来ICarBoat要返回两个答案就必须有两个方法了,我们假设一个方法是求在陆地上奔跑的速度,名称为GetCarMaxSpeed();另一个方法是求在大海上航行的最大速度,名称为GetBoatMaxSpeed();那这两个方法又怎么和GetMaxSpeed()接口方法联系起来呢;幸运的是,我们找到了解决办法,而且解决办法有很多种,下面介绍一下继承法。class IXCar:public ICar(virtual int GetMaxSpeed()(GetCarMaxSpeed(

21、);)201SC基本知识 附录:名 词 解 释virtual int GetCarMaxSpeed()=0;;class IXBoat:public IB oat(virtual int GetMaxSpeed()(GetBoatMaxSpeed();)virtual int GetBoatMaxSpeed()=0;);classCCarBoat:public IXCar,public IXBoat(virtual int GetCarMaxSpeed()virtual int GetBoatMaxSpeed();211SC基本知识附录:名词解释图6多重接口与方法名冲突问题1.2.3 this

22、跳转th is跳转是指的“对象同一性”问题。在单一继承的世界内,无论继承关系怎么复杂,针对于同一对象,无论它的子类或者父类的th is指针永远相等。即如果有下面的模型:图7 B从A继承的关系图221SC基本知识 附录:名词解释那么对于一个已经实例化B 类的对象b O b j e c t,永远有(B*)&b O b j e c t=(A*)&b O b j e c t 成立。但是在多继承的世界内,上面的等式就不能恒成立,对象的同一性受到了挑战。特别的是,在多继承世界内如果图四的菱形关系存在情况下,如果对于已经实例化B 类的对象b O b j e c t;(B a s e*)(A l*)&b O

23、b j e c t !=(B a s e*)(A 2*)f e b O b j e c t 成立,当这种事情发生的时候我们就只能特殊处理了。这种情况在C O M 应用中处处都会发生。1.3 C+多态的两种多态形式和区别C+有两种多态多态形式:1、编译时刻多态,编译时刻多态依靠函数重载或者模板实现2、运行时刻多态。运行时刻多态依靠需函数虚接口实现第二章 重载学习要求:1、了解什么是函数重载,什么是运算符重载2、学会运用智能指针,仿函数在 C+的世界里,有两种重载:函数重载和运算符重载,函数重载就采用采用参数匹配的原则,进行重载的,它是一种编译时刻的多态。而运算符重载,使采用改写或者说重新定义C+

24、的内嵌运算符的方法。231SC基本知识 附录:名词解释有关重载的基本概念:Overloaded FunctionsOverloaded OperatorsDeclaration MatchingArgument MatchingArgument Types MatchingArgument Counts MatchingC+Unary OperatorsBinary OperatorsSmart PointerFunction objects1.1 函数重载函数重载方法是在当前范围内选择一个最佳匹配的函数声明供调用该方法者使用。如果一个适合的函数被找到后,这个函数将会被调用,在这 里“适合的”

25、是指按下列顺序匹配的符合下面条件的:1、一个精确匹配的函数被找到2、一个参数只有细微的差别,几乎可以忽略不计的。3、象类似通过子类向父类转化达到参数匹配的4、通过正常转化函数进行类型转换,能够达到参数匹配到的。5、通过用户自定义的转化函数(如转化运算符或者构造函数)达到参数匹配的6、参数是采用省略符号241SC基本知识 附录:名词解释函数重载的方法基本上有:1、根据函数参数数据类型的不同进行的重载;2、根据参数个数的不同进行的重载;3、缺省参数上的重载我们在这里把缺省参数也称为一种函数重载,实际上它并不是严格意义上的重载。在使用缺省参数时必须记住两条规则。第一,只有参数列表的后部参数才可是缺省

26、的,也就是说,我们不可以在一个缺省参数后面又跟一个非缺省的参数。第二,一旦我们开始使用缺省参数,那么这个参数后面的所有参数都必须是缺省的。第三,缺省参数只能放在函数声明中。第四,缺省参数可以让声明的参数没有标识符。4、返回值重载特别注意,在C+中并没有根据返回返回值的不同进行重载的,即我们不能定义这样的函数:v o i d f ();i n t f 0;在C+中这样的函数声明方法是被禁止的,但是我们有时间可能又需要这样的重载方法,我们又怎么实现呢,其实很简单,j i a n g函数的参数进行扩展,将这个函数返回值的数据类型,做为扩展参数的数据类型来。如下:v o i d f (v o i d)

27、;v o i d f (i n t);此时这个例子中的参数列表的数据,只在编译时刻起到分练函数的作用,在运行时刻并不起到传值作用,模板中经常都应用到了这种方法。251SC基本知识 附录:名词解释1.2 运算符重载你可以重新定义C+绝大多数内嵌运算符的实现方法和功能,这些重定义的或者说重载的运算符,有可能全局作用的,也有可能作用在类基础之上的,运算符重载的实现可能以类的成员函数的形式出现,也有可能以全局性的函数的身份出现。在 C+中重载运算符的名字为o p e r a t o r 上,在这里x 是一个可重载的运算符,如:重载加法运算符,你需要定义一个名为o p e r a t o r+的函数,然

28、后实现他,其它的类似定义就可以了,例如:Class complex/very simplified complex(doublere,im;public:complex(doubler,doublei):re(r),im(i);complex operator+(complex);complex operator*(complex););定义了 complex这个复数的一个简单的实现概念模型。一个复数是由一对double类型的数据组成,并定义了这个复数的两个方法,加法运算complex:operartor+()和乘法运算 complex:operator*().现在我们就能够实现下面的复数表达

29、式了:261SC基本知识 附录:名词解释v o i d f ()c o m p l e x a =c o m p l e x (1 ,3.1);c o m p l e x b =c o m p l e x(1.2 ,2);c o m p l e x c =b;a =b +c;b =b +c *a;c=a *b +c o m p l e x (1 ,2);)1.3.1 C+可重载的和C+不可重载的运算符可重载运算符表:O p e r a t o r N a m eT y p e O p e r a t o r N a m e T y p e,Co m m aB i n a r y -*P o i

30、 n t e r-t o-m e m b e r B i n a r ys e l e c t i o n!L o g i c a l N O TU n a r y /D i v i s i o n B i n a r y27ISC基本知识附录:名词解释1 =I n e q u a l i t yB i n a r y/=D i v i s i o n/a s s i g n m e n t B i n a r y%M o d u l u sB i n a r yL e s s t h a nB i n a r y%=M o d u l u s/a s s i g n m e n tB i n

31、 a r yL e f t s h i f tB i n a r y&B i t w i s e A N DB i n a r y=L e f ts h i f t/a s s i g n m e n tB i n a r y&A d d r e s s-o fU n a r yG r e a t e r t h a nB i n a r y*M u l t i p l i c a t i o nB i n a r y=G r e a t e r t h a n o re q u a l t oB i n a r y*P o i n t e r d e r e f e r e n c eU n

32、 a r yR i g h t s h i f tB i n a r y*=M u i t i p l i c a t i o n/a s s i g n B i n a r y=R i g h ts h i f t/a s s i g n m e n tB i n a r y+A d d i t i o nB i n a r yA r r a y s u b s c r i p t+U n a r y P l u sU n a r yE x c l u s i v e O RB i n a r y+I n c r e m e n t1U n a r y-二E x c l u s i v eO

33、 R/a s s i g n m e n tB i n a r y+=A d d i t i o n/a s s i g n m e n tB i n a r y1B i t w i s e i n c l u s i v e O R B i n a r yS u b t r a c t i o nB i n a r y1=B i t w i s e i n c l u s i v eB i n a r y281SC基本知识 附录:名词解释O R/a s s i g n m e n tU n a r y n e g a t i o nU n a r yIIL o g i c a l O RB

34、i n a r y-D e c r e m e n t U n a r yO n e s c o m p l e m e n tU n a r y-=S u b t r a c t i o n/a s s i g nB i n a r y d e l e t ed e l e t e-M e m b e r s e l e c t i o nB i n a r yn e w不可重载运算符表:O p e r a t o r N a m eM e m b e r s e l e c t i o n.*P o i n t e r-t o-m e m b e r s e l e c t i o n S

35、 c o p e r e s o l u t i o n?:C o n d i t i o n a l#P r e p r o c e s s o r s y m b o l#P r e p r o c e s s o r s y m b o l在上面可重载的运算符可以看出运算符重载共分为两类:一元运算符重载和二元运算符重载一元运算符重载:291SC基 本 知 识 附 录:名 词 解 释在声明一个类的非静态的一元运算符重载函数时,你必须声明的形式如 下:ret-type operator?/?()(1)在这里ret-type是指返回数据类型op是指一元运算符在声明一个全局的一元运算符重载函数时

36、,你必须声明的形式日下:ret-type operatoro/?(arg)(2)在这里ret-type与o p和上面的意思一样,arg是指这个运算符所作用的数据类型二元运算符重载:在声明一个类的非静态的二元运算符重载函数时,你必须声明的形式如 下:ret-type operator op(arg)(3)(3)式和二式基本相同a rg可以是任何一个在声明一个全局的二元运算符重载函数时,你必须声明的形式日下:ret-type operatorop(argJ,arg公(4)在这里ret-type与op和上面的意思一样,argl,arg2,是指这个运算 符所作用两个数据类型301SC基本知识附录:名词

37、解释1.3.2几类特殊的运算符重载1、类型转换运算符所有的数据类型均可以定义构造函数,包括系统定义的数据类型和用户自定义的数据类型,如:class CString(operator LPCSTR()const;);应用:CString str=12345”;LPCSTR Ipsz=str;此处会进行LPCSTR运算这只是一个简单的应用的示例,其实有时间类型转换具有无比强大的功能。我曾经就是用类型装换运算符重载解决一个跨平台通信的问题。2、bool运算符重载int、float、bool等运算符也是可以重载的,例如重载bool运算符,但是重载运算符bool时候,需要注意有很多麻烦和臆想不到的东西t

38、emplateclass testbool(operator bool()const throw()311SC基本知识附录:名词解释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;i f (s p l =s p 2)i f (s p l !=s p 2)b o o l b =s p li n t I =s p l *1 0;从上面可以看得出b o o l 的表现已经远远超过b o o l 本身了,所以建议大家不要轻易对b

39、o o l 进行重载操作。3、地址运算符重载在DCOM应用中,我们有一个重载运算符的例子:STDAPI CoCreatelnstance(REFCLSID r c lsid,LPUNKNOWN pUnkOuter,DWORD dwClsContext,REFIID r iid,LPVOID*ppv);我们看最后一个参数L P V O ID指针的指针,这里是一个输出参数,返回一个接口的指针。一般情况下我们应用如下32ISC基本知识 附录:名 词 解 释IUnknown*pUn;C o C re a te In s ta n c e(v o id *)&pUn);(5)然而我们也可以这样写:IUn

40、known*pUn;CComPtr comPtr(pUn);C o C re a te I n s ta n c e(.,(void*)&comPtr);(6)之所以能够这么写这是因为CComPtr重载了 运算符,如下:template class CComPtr(public:CComPtr。*Ip)|if(p=p)!=NULL)p-AddRef();)T*operator&()|ATLASSERT(p=NULL);return&p;)private:T*p;);331SC基本知识附录:名词解释&c o m P t r实际上是得到了一般的情况下,我们并不能对p U n的地址,所 以(5)式

41、和(6)式其实传入的参数是一样当都是传入了 pUn的地址。虽然我们能够对运算符进行重载,但一般情况下我们并不是很提倡这种操作,这是因为:A、暴露了封装对象的地址,如上面C C o m P t r对p U n的封装其实不起任何作用,任何时候我都可以直接访问和修改p U n指针,这就意味着所有权的完全丧失,封装不起任何意义B、对 于u n a r y o p e r a t o r&的重载使得重载对方永远无法与S T L容器进行任何融合,甚至无法参与任何泛型编程。一个对象的地址是一个对象最基本的概念,在一般情况下,我们并不提倡,也请大家慎用地址运算符的重载。4、指针运算符重载指针运算符,有一个及其

42、特殊且及其重要的机制:当你对某个型别实施o p e r a t o r-而这个型别并非原生指针时候:编译器会从这个型别中找出用户自定义的o p e r a t o r-),并实 施 后,编 译 器 将 继续对这个o p e r a t o r-返回的结果实施o p e r a t o r-直到找到一个原生指针。这种机制导致了一个特有的技术:(p r e a n d p o s t fu n c t i o nc a l l s ),“前调用”及后调用技术。应用如下:c l a s s C a l l D o S o m e t h i n g(p u b l i c:vo i d D o C

43、a l l Q341SC基本知识 附录:名 词 解 释TRACE(DoCalln););templateclass CalllnMutiThreadclass LockProxy(public:LockProxy(T*pT):m_pT(pT)TRACE(Lockn);)LockProxy()(TRACE(UnLock n);)T*operator-()(return m_pT;)private:T*m_pT;);public:CallInMutiThread(T*pT):m_pT(pT)351SC基本知识附录:名词解释)LockProxy operator-()(return LockProx

44、y(m_pT);)private:T*m_pT;;上 面CallDoSomething是函数调用,假设这个类原来是在单线程中运 行 的,但是现在已经移植到了多环境中,所以我们就增加了CalllnMutiThread对 原始类进行配接使之适应与多线程环境,调用过程如下:CallDoSomething DoSomthing;CallInMutiThreadMutiThread(&DoSomthing);MutiThread-DoCall();调用结果如下:LockDoCallUnLock从上面可以看出在调用CallDoSomething的成员函数DoCall之前调用了 Lock方法,在调用结束后有

45、调用了UnLock。这就是所谓的“前调用”和“后调用”,其实并不仅仅是多线程问题可以采用此办法,所 有 的“前调用”和“后调用”模式均可由此解。重 载“-”运算符,同时引出了智能指针的概念,参见下页。5、括号运算符重载361SC基本知识 附录:名词解释语法特征:primary-expression(expression-listop)括号运算符是一个同“-”运算符一样也是一个及其重要的运算符在M SDN上 说 括号运算符是一个二元运算符,我觉得这个说法是完全错误的,在所有C+运算符重载中,括号运算符,应该是唯一没有规定参数元的个数的。它的参数可以从0 个 到 N个。示例:class Point

46、(public:Point()_x=_y=0;Point&operator()(int dx,int dy)_x+=dx;_y+=dy;return*this;private:int _x,_y;);调用如下:Point pt;pt(3,2);从上面可以看出,括号运算符,调用形式如下:object parameter list);看起来和函数的形式是完全一样的:fu n c t i o n parameter list);所以根据这一特点我们称之为仿函数。3 7ISC基本知识附录:名词解释第三章 模板学习要求:1、了解什么是模板2、学会运用模板函数,模版类和S T L模 板(t e m p l

47、 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 r y (简称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 的基本概念和语言特性1.1 认识模板1、模板的基本语法是:te m p l a te declaration这个te m p l a te 描述了一个参数化的

48、类(模板类)或者是一个参数化的函 数(模板函数),这个模板参数列表是用逗号分隔的类型列表(在这个表单忠使用c l a ss或者是typ e n a m e 来标识这个数据类型)。在某些情况下这个模板体内可能不存在任何的数据类型。declaration域必须是一个函数或者类的声明。1.4模板函数381SC基本知识 附录:名词解释语法定义:templatefunction-name(parameter list)例如:template inline T const&max(T const&a,T const&b)/if a b then use b else use areturn a b?b:a

49、;)调用形式:1 :通过调用的参数来识别模板的各参数类型MAX(4,4.2);/OK,but type of first argument definesreturn type2:明确指定参数的类型:MAX(4,4.2);/OK在我们的例子中这个参数列表是typename T,其实在这里typename是可以用class替换的,typename是在C+演化过程中逐渐形成的,而class是一个历史性的概念,typename表达了一个比class更抽象意义上的概念。有如下定义如:class typenamedeftypedef int INT_TYPE;391SC基本知识 附录:名词解释;如果这样

50、表达是正确的:templateclass testtypename:public typenamedef(public:typ e n a m e T:INT_TYPE;INT_TYPE m_int;);但 是 如 果 把 此 处 的 typ e n a m e 换 成class就会报错1.4.1 重载模板函数(Overloading Function Templates)和普通的函数一样,模板函数也可以被重载,也就是说对象同的函数名,你能够具有不同的函数定义,在调用的时候再由C+编译器决定,那一个候选函数更有资格被匹配调用。下面这个简单的例子说明了重载模板函数的方法和过程:/maximum

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

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

本站为文档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