C++中的类模板详细讲述
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、类模板定义及实例化
1. 定义一个类模板:
1 template
2
3class类名{
4
5// 类定义......
6
7};
其中,template 是声明类模板的关键字,表示声明一个模板,模板参数可以是一个,也可以是多个,可以是类型参数,也可以是非类型参数。类型参数由关键字class或typename及其后面的标识符构成。非类型参数由一个普通参数构成,代表模板定义中的一个常量。
例:
1 template
2
3//type为类型参数,width为非类型参数
4
5class Graphics;
注意:
(1)如果在全局域中声明了与模板参数同名的变量,则该变量被隐藏掉。
(2)模板参数名不能被当作类模板定义中类成员的名字。
(3)同一个模板参数名在模板参数表中只能出现一次。
(4)在不同的类模板或声明中,模板参数名可以被重复使用。
1 typedef string type;
2
3 template
4
5class Graphics
6
7 {
8
9 type node;//node不是string类型
10
11 typedef double type;//错误:成员名不能与模板参数type同名
12
13 };
14
15 template
16
17class Rect;
18
19 template
20
21class Round;
(5)在类模板的前向声明和定义中,模板参数的名字可以不同。
1// 所有三个 Image 声明都引用同一个类模板的声明
2
3 template
4
5 template
6
7// 模板的真正定义
8
9 template
10
11class Image { //模板定义中只能引用名字”Type”,不能引用名字”T”和”U” };
(6)类模板参数可以有缺省实参,给参数提供缺省实参的顺序是先右后左。
1 template
2
3class Image;
4
5 template
6
7class Image;
(7)类模板名可以被用作一个类型指示符。当一个类模板名被用作另一个模板定义中的类型指示符时,必须指定完整的实参表
1 template
2
3class Graphics
4
5 {
6
7 Graphics *next;//在类模板自己的定义中不需指定完整模板参数表
8
9 };
10
11 template
12
13void show(Graphics
14
15 {
16
17 Graphics
18
19 }
2.类模板实例化
定义:从通用的类模板定义中生成类的过程称为模板实例化。
例:Graphics
类模板什么时候会被实例化呢?
①当使用了类模板实例的名字,并且上下文环境要求存在类的定义时。
②对象类型是一个类模板实例,当对象被定义时。此点被称作类的实例化点。
③一个指针或引用指向一个类模板实例,当检查这个指针或引用所指的对象时。例:
1 template
2
3class Graphics{};
4
5void f1(Graphics
6
7class Rect
8
9 {
10
11Graphics
12
13Graphics
15 }
16
17int main(){
18
19Graphcis
21f1(*sc);//需要实例化,因为传递给函数f1的是一个Graphics
22
23int iobj=sizeof(Graphics
Graphics
24
25 }
3.非类型参数的模板实参
要点:
①绑定给非类型参数的表达式必须是一个常量表达式。
②从模板实参到非类型模板参数的类型之间允许进行一些转换。包括左值转换、限定修饰转换、提升、整值转换。
③可以被用于非类型模板参数的模板实参的种类有一些限制。
例:
1 Template
2
3 Template
4
5constint size=1024;
6
7 Graphics<&size> bp1;//错误:从const int*->int*是错误的。
8
9 Graphics<0> bp2;//错误不能通过隐式转换把0转换成指针值
10
11constdouble db=3.1415;
12
13 Rect
14
15 unsigned int fasize=255;
16
17 Rect
18
19 Int arr[10];