《C++中级培训教材.docx》由会员分享,可在线阅读,更多相关《C++中级培训教材.docx(56页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、附件三:教材模板说明:、为便于保存和管理,各类培训教材均采用合订本。二、教材结构:各类培训教材由教材封面、前言、课程目录、单门课程教材和 封底五部分构成。三、教材封面:1、封面颜色:教材封面为彩色,工作基本常识教材为深蓝色, 技术基础知识教材为草绿色,管理基础知识教材为浅蓝色,营 销基础知识教材为墨绿色。2、教材名称:采用“工作基本常识”“技术基础知识”“管 理基础知识” “营销基础知识”,字体为隶书,黑体,60号。3、其他标识:员培训中心编辑采用宋体、黑体、三号,位 于教材名称下面:华为技术有限公司采用宋体、黑体、小二, 位于底端;华为标识位于华为技术有限公司和员培训中心编 辑之间;右上角为
2、保密标识,楷体,黑体,四号。四、教材封底:教材封底包括教材名称、华为技术有限公司员培训中心和时 间、版本号,位于页面的右下角。五、前言:教材前言为各类培训的目的、课程门类、特点、主要内容的简 介。六、课程目录:为各门课程排列顺序的目录,统编排页码,便于学员查找。七、单门课程教材:各单门课程教材由课程封面、章节目录、章节内容、学习要求、 思考题、参考资料和相关网站组成。1、课程封面:课程封面为彩色,课程名称为隶书、60号、黑体、黑色,左上 角为课程编码。2、章节目录:为宋体、小四、黑色3、章节内容:(1)标题:章节目分别以“第一章、第二章、第三章”“ 1.1、 1.2、1.3”和“(1) (2)
3、 (3) ”来表示。章为宋体、小二、 黑体,节为宋体、四号、黑体,目为宋体、小四、黑体。(2)文字:每四个小时的培训课程,字数控制在10000 20000字之间。教材文字一般为宋体、小四、黑色,行间距为 一行半。(3)内容:章节内容要有完整的理论体系,不能成为授课胶 片的翻版。4、学习要求:每章标题下面为本章的学习要求,以明确本章要掌握的要点。 文字为楷体、小四。5、思考题:每章最后要有思考题,以便帮助学员复习、思考。6、参考资料和相关网站:有参考资料和相关网站的要附在课程后面,以便帮助学员查 阅。内部资料,注意保密C+中 级培训 教程员培训中心 编辑2005年6月 VI. 0华为技术华为技术
4、有限公司时 言C+语言中级教材讲授C+语言的运用技术,包括:类、 对象之间的关系、对象的存储与布局、运算符重载、智能指针、 仿函数、泛型编程,C+模式设计基本思想。NE002009cVl. 01业务与软件C+语言项目C+进阶 71. 1Handle-Body 与接 口、抽象接 71.2 多继承、与菱形缺陷、this跳转等131.3 C+多态的两种多态形式和区别18第 二 章重载,182.1 函 数 重载,192.2 运 算 符 重载 20第三章模板 -293.1模块函数 -293.2 模块类313.3 STL标准模板库34附录:参考资料39前言我们在C+基础课程中已经了解了C+的些基本概念,知
5、道 了什么是类什么是对象。也了解了继承、封装、多态等C+面向 对象的基本特征,本课程主要是更进步探讨一下C+些基本 模型的应用,加深对概念的理解,由于课程时间有限,C+,模 型和内容又如此之多,对任何一个模型都无法深入进去,所以只 能泛泛而谈。第一章 类、接口学习要求:1、了解类的继承、封装等概 念之间的关系2、了解什么是接口,什么是虚函数, 它有什么样的特点。学会使用接口编程的思想本章节主要介绍C+中的类、接口。类,包涵了一组数据 和一组基于数据上的组方法。它描述了一个对象的属性、状态 和行为;接口,它只是描述了一个对象的简单的行为。有关类的基本概念:Class namesClass mem
6、bersMember FunctionsStatic Member FunctionsUnionsC+ Bit FieldsNested Class DeclarationsType Names in Class ScopeMultiple Base ClassesVirtual FunctionsAbstract ClassesControlling Access to Class Membersprivate Membersprotected Members public MembersAccess Specifiers for Base Classes, priavte, public
7、protectedFriendsConstructorsDestructorsConversion Functionsthe new operator and the delete operator Copying Constructor Functions Interface1. 1 Handle-Body与接口、抽象接口在C+中封装的概念是把个对象的外观接口同实际工作方 式(实现)分离开来,但是C+的封装是不完全的,编译器必须 知道一个对象的所有部分的声明,以便创建和管理它。我们可以 想象一种只需声明一个对象的公共接口部分的编程语言,而将私 有的实现部分隐藏起来。C + +在编译期间要尽可
8、能多地做静态类 型检查。这意味着尽早捕获错误,也意味着程序具有更高的效率。 然而这对私有的实现部分来说带来两个影响:是即使程序员不 能轻易地访问实现部分,但他可以看到它:是造成一些不必要 的重复编译。然而C+并没有将这个原则应用到二进制层次上,这是因为C+的类既是描述了一个接口同时也描述了实现的过程,示例如下:class CMyString(private:const int m_cch;char *m_psz;public:CMyString(const char *psz);-CMyStringO;int Length() const;int Index(const char *psz)
9、const;CMyStirng对外过多的暴露了内存布局实现的细节,这些信息过度 的依赖于这些成员变量的大小和顺序,从而导致了客户过度依赖1SC基本知识附录:名词解释于可执行代码之间的二进制耦合关系,这样的接口不利于跨语言 跨平台的软件开发和移植。1.1.1 Handle-Body 模式解决这个问题的技术有时叫句柄类(handle classes)或 叫“ Cheshire Cat 1 I0有关实现的任何东西都消失了,只剩 个单的指针“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;);CMyStringHandle: CMyStringHandle(const char
11、*psz) :m_pThis(new CMyString(psz);(CMyStringHandle;- CMyStringHandle()(delete m_pThis;int CMyStringHandle:;Length()(return m_pThis-Length();int CMyStringHandle:;Index(const char *psz)(return m_pThis-Index(psz);这是所有客户程序员都能看到的。这行class CMyString;是个没有完全指定的类型说明或类声明(个类的定义包含类 的主体)。它告诉编译器,Cheshire是个结构的名字,但没
12、有 提供有关该结构的任何东西。这对产生一个指向结构的指针来说 已经足够了。但我们在提供个结构的主体部分之前不能创建一1SC基本知识附录:名词解释个对象。在这种技术里,包含具体实现的结构主体被隐藏在实现 文件中。在设计模式中,这就叫做Handle-Body模式,Handle-Body 只含有一个实体指针,服务的数据成员永远被封闭在服务系统中。 Handle-Body模式如:classHandlem_pThis I class图1 Handle-Body模式(句柄类做为接口)Handle - Body的布局结构永远不会随着实现类数据成员的加入或 者删除或者修改而导致Hand 1 e-Body的修改
13、,即Hand 1 e-Body协议 不依赖于C+实现类的任何细节。这就有效的对用户的编译器隐藏 了这些斜街,用户在使用对这项技术时候,Handle-Body接口成 了它唯一的入口。然而Handle-Body模式也有自己的弱点:1、接口类必须把每个方法调用显示的传递给实现类,这在个只有一个构造和一个析构的类来说显然不构成负1SC基本知识附录:名词解释担,但是如果一个庞大的类库,它有上百上千个方法时候, 光是编写这些方法传递就有可能非常冗长,这也增加了出 错的可能性。2、对于关注于性能的应用每个方法都得有两层的函数 调用,嵌套的开销也不理想3、由于句柄的存在依然存在编译连接器兼容性问题。接口和实现
14、分离的Handle-Body LL2抽象接口使用了 “接口与实现的分离”技术的Handle-Body解决了 编译器/链接器的大部分问题,而C+面向对象编程中的抽象接口 同样是运用了 “接口与实现分离”的思想,而采用抽象接口对于 解决这类问题是个极其完美的解决方案。1、抽象接口的语言描述:class IMyString(virtual int Length() const = 0; 这表示是个纯虚函 数,具有纯虚函数的接口virtual int Index(const char *psz) const = 0;1SC基本知识附录:名词解释2、抽象接口的内存结构:图2抽象接口的内存布局3、 抽象接
15、口的实现代码:接口:class IMyString (virtual int Length() const = 0; 这表示是个纯虚 函数,具有纯虚函数的接virtual int Index(const char *psz) const = 0;); 实现: class CMyString: public IMyStringprivate:const int m_cch;char *m_psz;public:CMyString(const char *psz);virtual -CMyStringO;int Length() const;int Index(const char *psz) c
16、onst;从上面采用抽象接口的实例来看,抽象接口解决了 Handle-Body所遗留下来的全部缺陷。抽象接口的个典型应用:抽象厂(AbstractFactroy)MotrfFackXYreturn new PMButtociCf9t0ScroilBar() CrtMuttonO CwMcnuf)CrBBteScroABart) Crwte8uflon() CreateMwM)CatScro8ar() 0Oote6utton() OeateMenuQrMum new PMMonu 1PM FactoryMacFactoryCrMtoScroneart) 0 CmsButtan() CrMAeMQ
17、nuOntixn new MacButton return new MacScrollBa?return new P1SC基本知识附录:名词解释图3抽象工厂模式1.2多继承与菱形缺陷、this跳转等多重继承是C+语言独有的继承方式,其它几乎所有语言都 秉承了单继承的思想。这是因为多重继承致命的缺陷导致的: 1.2.I菱形缺陷当继承基类时,在派生类中就获得了基类所有的数据成员副 本。假如类B从A1和A2两个类多重继承而来,这样B类就包 含Al、A2类的数据成员副本。考虑如果Al、A2都从某基类派生,该基类称为Base,现 在继承关系如下:图4麦形继承关系我们C+语言来描述这种继承关系:class
18、 Base ;class Al :public Base ;1SC基本知识附录:名词解释class A2 :public Base ;class B :public Al, public A2 ;那么Al、A2都具有Base的副本。这样B就包含了Base的两个 副本,副本发生了重叠,不但增加了存储空间,同时也引入 了二义性。这就是菱形缺陷,菱形缺陷时间是两个缺陷:1、 子对象重叠2、向上映射的二义性。菱形缺陷的其中一种解决办法将在C+世界里最广泛的使用虚拟继承解决菱形缺陷的应用便 是标准C+的输入/输出iostream;basicjosiostream图5标准C+的输入/输出1.2.2 多重接
19、口与方法名冲突问题(Siamese twins)对继承而来的虚函数改写很容易,但是如果是在改写个 “在两个基类都有相同原型”的虚函数情况就不那么容易了。1SC基本知识附录:名词解释提出问题:假设汽车最大速度的接口为ICar,潜艇最大速度的接口为 IBoat,有一个两栖类的交通工具它可以奔跑在马路上,也可以航 行在大海中,那么它就同时拥有ICar、IBoat两种交通工具的最大 速度特性,我们定义它的接口为ICarBoat;class ICar(virtual int GetMaxSpeed ()=0;class IBoat(virtual int GetMaxSpeed ( ) = 0;1;我们
20、先对ICarBoat的接口做个尝试:class CCarBoat(virtual int GetMaxSpeed();既完成ICar的GetMaxSpeed 接口方法又完成IBoat的接口方法?显然不能够);解决问题:1SC基本知识附录:名词解释显然上面这个尝试根本就无法成功,只用个实现方法,怎 么能够求出这个ICarBoat交通工具奔跑在马路上的最高时速,同时 也能够求出航行在大海上的最大航行速度呢。上面这问题矛盾就在个方法,却需要两个答案。看来 ICarBoat要返回两个答案就必须有两个方法了,我们假设个方法 是求在陆地上奔跑的速度,名称为GetCarMaxSpeed ;另个 方法是求在大
21、海上航行的最大速度,名称为GetBoatMaxSpeed (); 那这两个方法又怎么和GetMaxSpeed 接口方法联系起来呢;幸运的是,我们找到了解决办法,而且解决办法有很多种, 下面介绍一下继承法。class IXCar :public ICar(virtual int GetMaxSpeed ()GetCarMaxSpeed();virtual int GetCarMaxSpeed ( ) = 0;1;class IXBoat:public IBoat(virtual int GetMaxSpeed ()GetBoatMaxSpeed();virtual int GetBoatMaxS
22、peed () = 0;classCCarBoat: public IXCar , public IXBoatvirtual int GetCarMaxSpeed () virtual int GetBoatMaxSpeed ()1SC基本知识附录:名词解释图6多重接口与方法名冲突问题1.2.3 this跳转this跳转是指的“对象同一性”问题。在单继承的世界内,无论继承关系怎么复杂,针对于同一 对象,无论它的子类或者父类的this指针永远相等。即如果有下 面的模型:A (IJ BJ图7 B从A继承的关系图那么对于个已经实例化B类的对象bObject,永远有(B*) &bObject = (A
23、*)&bObject 成立。但是在多继承的世界内,上面的等式就不能恒成立,对象的 同一性受到了挑战。特别的是,在多继承世界内如果图四的菱形关系存在情况 下,如果对于已经实例化B类的对象bObject; (Base*) (Al*) &bObject != (Base*) (A2*) &bObject 成立,当这种事情发生 的时候我们就只能特殊处理了。这种情况在COM应用中处处都会发 生。1. 3 C+多态的两种多态形式和区别C+有两种多态多态形式:1、编译时刻多态,编译时刻多态依靠函数重载或者模板实 现2、运行时刻多态。运行时刻多态依靠需函数虚接口实现第二章重载学习要求:1、了解什么是函数重载,
24、什么是运算符重载2、学会运用智能指针,仿函数在C+的世界里,有两种重载:函数重载和运算符重载,函数重 载就采用采用参数匹配的原则,进行重载的,它是种编译时刻 的多态。而运算符重载,使采用改写或者说重新定义C+的内嵌 运算符的方法。1SC基本知识附录:名词解释有关重载的基本概念:Overloaded FunctionsOverloaded Operators Declaration Matching Argument MatchingArgument Types MatchingArgument Counts Matching C+ Unary OperatorsBinary Operators
25、Smart PointerFunction objects1、 I函数重载函数重载方法是在当前范围内选择个最佳匹配的函数声 明供调用该方法者使用。如果一个适合的函数被找到后,这个函 数将会被调用,在这里“适合的”是指按下列顺序匹配的符合下 面条件的:2、 个精确匹配的函数被找到3、 一个参数只有细微的差别,几乎可以忽略不计的。4、 象类似通过子类向父类转化达到参数匹配的4、通过正常转化函数进行类型转换,能够达到参数匹配到 的。5、通过用户自定义的转化函数(如转化运算符或者构造函 数)达到参数匹配的1SC基本知识附录:名词解释6、参数是采用省略符号函数重载的方法基本上有:1、 根据函数参数数据类
26、型的不同进行的重载;2、 根据参数个数的不同进行的重载;3、 缺省参数上的重载我们在这里把缺省参数也称为种函数重载,实际上它并不 是严格意义上的重载。在使用缺省参数时必须记住两条规则。第 一,只有参数列表的后部参数才可是缺省的,也就是说,我们不 可以在个缺省参数后面又跟个非缺省的参数。第二,一旦我 们开始使用缺省参数,那么这个参数后面的所有参数都必须是缺 省的。第三,缺省参数只能放在函数声明中。第四,缺省参数可 以让声明的参数没有标识符。4、 返回值重载特别注意,在C+中并没有根据返回返回值的不同进行 重载的,即我们不能定义这样的函数:void f ();int f ();在C+中这样的函数声
27、明方法是被禁止的,但是我们有时间 可能又需要这样的重载方法,我们又怎么实现呢,其实很简单, jiang函数的参数进行扩展,将这个函数返回值的数据类型,做为 扩展参数的数据类型来。如下:void f (void);1SC基本知识附录:名词解释void f (int);此时这个例子中的参数列表的数据,只在编译时刻起到分练 函数的作用,在运行时刻并不起到传值作用,模板中经常都应用 到了这种方法。1.2运算符重载你可以重新定义C+绝大多数内嵌运算符的实现方法和功 能,这些重定义的或者说重载的运算符,有可能全局作用的,也 有可能作用在类基础之上的,运算符重载的实现可能以类的成员 函数的形式出现,也有可能
28、以全局性的函数的身份出现。在C+中重载运算符的名字为peratorx,在这里x是个 可重载的运算符,如:重载加法运算符,你需要定义个名为 operator+的函数,然后实现他,其它的类似定义就可以了,例 如:Class complex /very simplified complexdoublere, im;public:complex (doubler, doublei):re(r), im(i);complex operator+(complex);complex operator*(complex);1 ;定义了 complex这个复数的个简单的实现概念模型。个 复数是由一对double
29、类型的数据组成,并定义了这个复数的两个 方法,加法运算complex: :operartor+ ()和乘法运算 complex: :operator* ().现在我们就能够实现下面的复数表达式 了:void f ()complexcomplex(1 , 3. 1);complex bcomplex (1. 2,2);complexc * a;c= a * b + complex(1 , 2);1.3.1 C+可重载的和C+不可重载的运算符可重载运算符表:Operator NameType Operator NameCommaBinary - *Pointer-to-member selecti
30、on1*Logical NOTUnary/Division1 =InequalityBinary/=Division/assignmen%ModulusBinaryLess than%=Modulus/assignmentBinaryLeft shift&Bitwise ANDBinary=Leftshift/assignment&Address-ofUnaryGreater than*MultiplicationBinary=Greater than or equal to*Pointer dereferenceUnaryRight shift*二Muitiplicat ion/assign
31、Binary=Rightshift/assignment+AdditionBinaryArray subscript+Unary PlusUnaryExclusive OR+Increment1UnaryExclusiveOR/assignment+二Addition/assignmentBinary1Bitwise inclusive 0SubtractionBinary1=Bitwise inclusiveOR/assignmentUnary negationUnaryIILogical OR Decrement1UnaryOne s complement-Subtraction/assi
32、gnBinary deletedelete-Member selectionBinary new不可重载运算符表:OperatorName*Member selection.*Pointer-to-memberselection Scope resolution9 Conditional#Preprocessor symbol#Preprocessor symbol在上面可重载的运算符可以看出运算符重载共分为两类:一元运算符重载和二元运算符重载一元运算符重载:在声明一个类的非静态的一元运算符重载函数时,你必 须声明的形式如下:ret-type operator*()(1)在这里ret-type
33、是指返回数据类型op是指一元运算 符1SC基本知识附录:名词解释在声明一个全局的一元运算符重载函数时,你必须声明 的形式日下:ret-type operator4 arg ) (2)在这里ret-type与op和上面的意思样,arg是指 这个运算符所作用的数据类型二元运算符重载:在声明一个类的非静态的二元运算符重载函数时,你必 须声明的形式如下:ret-type operator。(財(3)(3)式和二式基本相同arg可以是任何个在声明一个全局的二元运算符重载函数时,你必须声明 的形式日下:ret-type operator0(財aZ, arg2) (4)在这里ret-type与op和上面的意
34、思样,argl, arg2, 是指这个运算符所作用两个数据类型1.3.2 几类特殊的运算符重载1、类型转换运算符所有的数据类型均可以定义构造函数,包括系统定义的数据类型和用户自定义的数据类型,如:class CStringoperator LPCSTR() const;应用:CString str = 12345”;LPCSTR Ipsz = str;此处会进行LPCSTR运算这只是一个简单的应用的示例,其实有时间类型转换具有 无比强大的功能。我曾经就是用类型装换运算符重载解决个跨 平台通信的问题。2、 bool运算符重载int、float、bool等运算符也是可以重载的,例如重载 bool运
35、算符,但是重载运算符bool时候,需要注意有很多 麻烦和臆想不到的东西 template class testbooloperator bool() const throw() (return m_ pT != 0;private:T *m_pT;1SC基本知识附录:名词解释下面结果均通过编译testbool spl;testbooKstd: :string sp2;if (spl = sp2)if (spl != sp2)bool b = splint I = spl * 10;从上面可以看得出bool的表现已经远远超过bool本身 了,所以建议大家不要轻易对bool进行重载操作。3、地址运
36、算符重载在DCOM应用中,我们有一个重载运算符的例子:STDAPI CoCreatelnstance( REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContexty REFI ID riidfLPVOID *pp);我们看最后个参数LPVOID指针的指针,这里是 个输出参数,返回一个接口的指针。一般情况下我们应用如下IUnknown *pUn;CoCreatelnstance,(void *)& pUn);然而我们也可以这样写:IUnknown *pUn;CComPtr comPtr(pUn);CoCreateInstance(,(void
37、 *)& comPtr);(5)之所以能够这么写这是因为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) 式其实传入的参数是样当都是传入了 pUn的地址。1SC基本知识附录:名词解释虽然我们能够对运算符进行重载,但一般情况下我们并 不
38、是很提倡这种操作,这是因为:A、 暴露了封装对象的地址,如上面CComPtr对pUn的封装其实不起任何作用,任何时候我都可以直接访问 和修改pUn指针,这就意味着所有权的完全丧失,封装 不起任何意义B、 对于unary operator&的重载使得重载对方永远 无法与STL容器进行任何融合,甚至无法参与任何泛型 编程。个对象的地址是个对象最基本的概念,在一般情况 下,我们并不提倡,也请大家慎用地址运算符的重载。4、指针运算符重载指针运算符,有一个及其特殊且及其重要的机制:当你对某个型别实施。perator-而这个型别并非 原生指针时候:编译器会从这个型别中找出用户自定义的 operator-并
39、实施后,编译器将继续对这个operator- 返回的结果实施operator-)直到找到个原生指针。这种机制导致了一个特有的技术:(pre and post function calls ),“前调用”及后调用技术。应用如下: class CallDoSomething ( public:void DoCallQTRACE(DoCalln););templateclass CalllnMutiThread (class LockProxy(public:LockProxy (T*pT) :m_pT(pT) (TRACE(Lockn);LockProxy() (TRACE(UnLock n);T
40、 *operator-() (return 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
41、 MutiThread(&DoSomthing);MutiThread-DoCall();调用结果如下:LockDoCallUnLock从上面可以看出在调用CallDoSomething的成员函数 DoCall之前调用了 Lock方法,在调用结束后有调用了 UnLock这就是所谓的“前调用”和“后调用”,其实并不 仅仅是多线程问题可以采用此办法,所有的“前调用”和“后 调用”模式均可由此解。重载“”运算符,同时引出了智能指针的概念,参见 下页。5、括号运算符重载语法特征:primary-expression (expression-listop)1SC基本知识附录:名词解释括号运算符是个同“”
42、运算符样也是个及其 重要的运算符在MSDN上说括号运算符是个二元运算符,我觉得这个说 法是完全错误的,在所有C+运算符重载中,括号运算符, 应该是唯一没有规定参数元的个数的。它的参数可以从0个 至UN个。示例:class Point ( 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
43、list);看起来和函数的形式是完全一样的:function parameter list);所以根据这特点我们称之为仿函数。第三章模板学习要求:1、了解什么是模板2、学会运用模板函数,模版类和SIL模板(templates),以及以模版为基础的泛型编程和泛型 模式,是当今C+中最活跃的项编程技术,模版的第一个革命性 的应用就是Standard Template Library (简称STL) STL将 templates技术广泛应用于STL容器和STL算法上,在这领域 template技术发挥到了极致。本章介绍C+ templates的基本概念和语言特性1.1 认识模板1、模板的基本语法是:template declaration这个template描述了一个参数化的类(模板类)或者是个 参数化的函数(模板函数),这个模板参数列表是用逗号分隔的 类型列表(在这个表单忠使用class或者是typename来标识这 个数据类型)。在某些情况下这个模板体内可能不存在任何的数 据类型。declaration域必须是一个函数或者类的声明。1SC基本知识附录:名词解释L4模板函数语法定义:template function