c++中的类模板详细讲述

上传人:第*** 文档编号:34210749 上传时间:2018-02-21 格式:DOCX 页数:21 大小:123.58KB
返回 下载 相关 举报
c++中的类模板详细讲述_第1页
第1页 / 共21页
c++中的类模板详细讲述_第2页
第2页 / 共21页
c++中的类模板详细讲述_第3页
第3页 / 共21页
c++中的类模板详细讲述_第4页
第4页 / 共21页
c++中的类模板详细讲述_第5页
第5页 / 共21页
点击查看更多>>
资源描述

《c++中的类模板详细讲述》由会员分享,可在线阅读,更多相关《c++中的类模板详细讲述(21页珍藏版)》请在金锄头文库上搜索。

1、一、类模板定义及实例化. 定义一个类模板:1 template2 3 class 类名4 5 / 类定义6 7 ;其中,template 是声明类模板的关键字,表示声明一个模板,模板参数可以是一个,也可以是多个,可以是类型参数 ,也可以是非类型参数。类型参数由关键字 class 或 typename 及其后面的标识符构成。非类型参数由一个普通参数构成,代表模板定义中的一个常量。例:1 template2 3 /type 为类型参数,width 为非类型参数4 5 class Graphics;注意:(1)如果在全局域中声明了与模板参数同名的变量,则该变量被隐藏掉。(2)模板参数名不能被当作类模

2、板定义中类成员的名字。(3)同一个模板参数名在模板参数表中只能出现一次。(4)在不同的类模板或声明中,模板参数名可以被重复使用。 1 typedef string type;2 3 template4 5 class Graphics6 7 8 9 type node;/node 不是 string 类型10 11 typedef double type;/错误:成员名不能与模板参数 type 同名12 13 ;14 15 template/错误:重复使用名为 type 的参数16 17 class Rect;18 19 template /参数名”type”在不同模板间可以重复使用20 21

3、 class Round;(5)在类模板的前向声明和定义中,模板参数的名字可以不同。1 / 所有三个 Image 声明都引用同一个类模板的声明2 3 template class Image;4 5 template class Image;6 7 / 模板的真正定义8 9 template 10 11 class Image /模板定义中只能引用名字”Type”,不能引用名字”T”和”U” ;(6)类模板参数可以有缺省实参,给参数提供缺省实参的顺序是先右后左。1 template 2 3 class Image;4 5 template 6 7 class Image;(7)类模板名可以被用

4、作一个类型指示符。当一个类模板名被用作另一个模板定义中的类型指示符时,必须指定完整的实参表1 template2 3 class Graphics4 5 6 7 Graphics *next;/在类模板自己的定义中不需指定完整模板参数表8 9 ;10 11 template 12 13 void show(Graphics &g)14 15 16 17 Graphics *pg=/必须指定完整的模板参数表18 19 类模板实例化定义:从通用的类模板定义中生成类的过程称为模板实例化。例:Graphics gi;类模板什么时候会被实例化呢?当使用了类模板实例的名字,并且上下文环境要求存在类的定义时

5、。对象类型是一个类模板实例,当对象被定义时。此点被称作类的实例化点。一个指针或引用指向一个类模板实例,当检查这个指针或引用所指的对象时。例:1 template2 3 class Graphics;4 5 void f1(Graphics);/ 仅是一个函数声明,不需实例化6 7 class Rect 8 9 10 11 Graphics/ 声明一个类模板引用,不需实例化12 13 Graphics si;/ si 是一个 Graphics 类型的对象 ,需要实例化类模板14 15 16 17 int main()18 19 Graphcis* sc;/ 仅声明一个类模板指针,不需实例化20

6、21 f1(*sc);/需要实例化,因为传递给函数 f1 的是一个 Graphics对象。22 23 int iobj=sizeof(Graphics);/需要实例化,因为 sizeof 会计算Graphics对象的大小,为了计算大小,编译器必须根据类模板定义产生该类型。24 25 3.非类型参数的模板实参要点:绑定给非类型参数的表达式必须是一个常量表达式。从模板实参到非类型模板参数的类型之间允许进行一些转换。包括左值转换、限定修饰转换、提升、整值转换。可以被用于非类型模板参数的模板实参的种类有一些限制。例:1 Template class Graphics.;2 3 Template cla

7、ss Rect.;4 5 const int size=1024;6 7 Graphics bp1;/错误:从 const int*int*是错误的。8 9 Graphics bp2;/错误不能通过隐式转换把转换成指针值10 11 const double db=3.1415;12 13 Rect fa1;/错误:不能将 const double 转换成 int.14 15 unsigned int fasize=255;16 17 Rect fa2;/错误:非类型参数的实参必须是常量表达式,将 unsigned 改为 const 就正确。18 19 Int arr10;20 21 Graph

8、ics gp;/正确二、类模板的成员函数要点:类模板的成员函数可以在类模板的定义中定义(inline 函数) ,也可以在类模板定义之外定义( 此时成员函数定义前面必须加上 template 及模板参数) 。类模板成员函数本身也是一个模板,类模板被实例化时它并不自动被实例化,只有当它被调用或取地址,才被实例化。1 template2 3 Class Graphics4 5 Graphics()/成员函数定义在类模板的定义中6 7 void out();8 9 ;10 11 template/成员函数定义在类模板定义之外12 13 void Graphics:out()三、类模板的友元声明类模板中

9、可以有三种友元声明:.非模板友元类或友元函数1 class Graphicsvoid out();2 3 Template4 5 Class Rect6 7 friend class Graphics;/类 Graphics、函数8 9 friend void create();/ create、 out 是类模板10 11 friend void Graphics:out();/ Rect 所有实例的友元12 13 ;2、绑定的友元类模板或函数模板。3、非绑定的友元类模板或函数模板。第二种声明表示类模板的实例和它的友元之间是一种一对一的映射关系。如图:第三种声明表示类模板的实例和它的友元之间

10、是一种一对多的映射关系。如图:例:绑定的友元模板1 template2 3 void create(Graphics);4 5 template6 7 class Graphics8 9 friend void create(Graphics);10 11 ;例:非绑定的友元模板1 template2 3 class Graphics4 5 template6 7 friend void create(Graphics);8 9 ;注意:当把非模板类或函数声明为类模板友元时,它们不必在全局域中被声明或定义,但将一个类的成员声明为类模板友元,该类必须已经被定义,另外在声明绑定的友元类模板或函数模

11、板时,该模板也必须先声明。例:1 template 2 3 class A 4 5 private:6 7 friend class B; /错误:类必须先声明8 9 ;10 11 template 12 13 class B;四、类模板的静态数据成员、嵌套类型.类模板的静态数据成员要点:静态数据成员的模板定义必须出现在类模板定义之外。类模板静态数据成员本身就是一个模板,它的定义不会引起内存被分配,只有对其实例化才会分配内存。当程序使用静态数据成员时,它被实例化,每个静态成员实例都与一个类模板实例相对应,静态成员的实例引用要通过一个类模板实例。例:1 template2 3 class Gra

12、phics4 5 static Graphics *next;6 7 static const type item;8 9 ;10 11 template12 13 Graphics * Graphics:next=0;14 15 template16 17 type Graphics:item=NULL;18 19 /静态成员定义分为两部分:前一部分是类型,比如 Graphics*,后一部分是名称和值,比如 Graphics:next=0;2.类模板的嵌套类型要点:在类模板中允许再嵌入模板,因此类模板的嵌套类也是一个模板,它可以使用外围类模板的模板参数。当外围类模板被实例化时,它不会自动被实

13、例化,只有当上下文需要它的完整类类型时,它才会被实例化。公有嵌套类型可以被用在类定义之外,这时它的名字前必须加上类模板实例的名字。例:1 template2 3 class Graphics4 5 public:6 7 template8 9 class Rectvoid out(type a,T b);10 11 ;12 13 Graphics:Rect node;14 15 /引用公有嵌套类型必须加上类模板实例名字五、成员模板定义:成员定义前加上 template 及模板参数表。要点:在一个类模板中定义一个成员模板,意味着该类模板的一个实例包含了可能无限多个嵌套类和无限多个成员函数只有当成

14、员模板被使用时,它才被实例化.成员模板可以定义在其外围类或类模板定义之外例: 1 template2 3 class Graphics4 5 public:template6 7 class Rectvoid out(type a,T b);8 9 template template10 11 void Graphics:Rect:out(Gtype a,TT b)/成员模板被定义在类模板定义之外(要根上完整模板实参)12 13 Graphics的实例可能包括下列嵌套类型:14 15 Graphics:Rect16 17 Graphics:Rect注意:类模板参数不一定与类模板定义中指定的名字

15、相同。六、类模板的编译模式1.包含编译模式这种编译模式下,类模板的成员函数和静态成员的定义必须被包含在“要将它们实例化” 的所有文件中,如果一个成员函数被定义在类模板定义之外,那么这些定义应该被放在含有该类模板定义的头文件中。2.分离编译模式这种模式下,类模板定义和其 inline 成员函数定义被放在头文件中,而非 inline 成员函数和静态数据成员被放在程序文本文件中。例: 1 /-Graphics.h-2 3 export template4 5 Class Graphics6 7 void Setup(const type 8 9 /-Graphics.c-10 11 #include “Graphics.h”12 13 Template 14 15 Void Graphics:Setup(const type &)16 17 /-user.c-18 19 #include “Graphics.h”20 21 Void main()22 23 Graphics *pg=new Graphics;24 25 Int ival=1;26 27 /Graphics:Setup(const int &)的实例(下有注解)28 29

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

当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号