没有合适的资源?快使用搜索试试~ 我知道了~
模板可以实现逻辑相同、数据类型不同的程序代码的复制,利用模板机制,程序具备更好的代码重用性能,可以减轻编程和维护的工作量和难度。
资源详情
资源评论
资源推荐
1
第十五章 C++模板
目录
第十五章 C++模板 .........................................................................................................................1
15.1 模板 .......................................................................................................................................... 2
15.2 函数模板 ..................................................................................................................................2
15.2.1 函数模板定义 ...............................................................................................................2
15.2.2 函数模板基础 ...............................................................................................................6
15.2.3 函数模板实例 ...............................................................................................................8
15.3 类模板 .................................................................................................................................... 11
15.3.1 类模板定义 ................................................................................................................. 11
15.3.2 类模板实例 .................................................................................................................15
15.4 线性表 .................................................................................................................................... 20
15.5 折半查找算法 ........................................................................................................................26
15.6 单链表(Singly Linked list)................................................................................................ 31
15.7 栈 ............................................................................................................................................36
2
15.1 模板
参数化程序设计:
通用的代码就必须不受数据类型的限制,可以把数据类型改为一个设计参数。这种类型的程序设计称
为参数化(parameterize) 程序设计。
这种设计由模板(template) 完成。包括函数模板(function template)和类模板(class template)。
C++ STL(Standard Template Library)技术是在 C++的模板技术发展起来的。在 C++的最新发展过程
中,C++新增了模板这个新特性,模板并非实实在在的类或函数,仅仅是一个类或函数的描述。模板可以
实现逻辑相同、数据类型不同的程序代码的复制,利用模板机制,程序具备更好的代码重用性能,可以减
轻编程和维护的工作量和难度。
函数模板提供了一种机制,通过它我们可以保留函数定义和函数调用的语义在一个程序位置上封装了
一段代码,确保在函数调用之前实参只被计算一次。函数模板提供一个种用来自动生成各种类型函数实例
的算法,程序员对于函数接口参数和返回类型中的全部或者部分类型进行参数化,而函数体保持不变。
15.2 函数模板
关键字 template 总是放在模板的定义与声明的最前面。关键字后面是用逗号分隔的模板参数表
(template parameter list ),它用尖括号(<>,一个小于号和一个大于号)括起来。通用格式:template<class
Type1[,class Type2…]>。
该列表是模板参数表,不能为空。模板参数可以是一个模板类型参数(template typeparameter ),它代表
了一种类型;也可以是一个模板非类型参数(template nontype parameter),它代表了一个常量表达式。
模板类型参数由关键字 class 或 typename 后加一个标识符构成。在函数的模板参数表中,这两个关键
字的意义相同。它们表示后面的参数名代表一个潜在的内置或用户定义的类型。模板参数名由程序员选择。
当模板被实例化时,实际的内置或用户定义类型将替换模板的类型参数。类型 int, double,char*,
vector<int>或 list<double>*都是有效的模板实参类型。
15.2.1 函数模板定义
template<类型 1 变量 1,类型 2 变量 2,…> 返回类型 函数名(形参表)
{
函数定义体;
}
模板非类型参数由一个普通的参数声明构成。模板非类型参数表示该参数名代表了一个潜在的值,而
该值代表了模板定义中的一个常量。例如,size 是一个模板非类型参数,它代表 arr 指向的数组的长度:
template <class Type, int size>
Type min(Type(&arr)[size]);
3
当函数模板 min()被实例化时,size 的值会被一个编译时刻已知的常量值代替。函数定义或声明跟在模
板参数表后。除了模板参数是类型指示符或常量值外,函数模板的定义看起来与非模板函数的定义相同。
我们来看一个例子:
template<class Type,int size>
Type min(const Type(&r_array)[size])
{
//寻找数组中最小值
Type min_val = r_array[0];
for(int i=1;i<size;i++)
{
if(r_array[i] < min_val)
{
min_val = r_array[i];
}
}
return min_val;
}
我们的例子中,Type 表示 min()的返回类型、参数 r_array 的类型,以及局部变量 min_val 的类型。size
表示 r_array 引用的数组的长度。在程序的运行过程中,Type 会被各种内置类型和用户定义的类型所代替,
而 size 会被各种常量值所取代,这些常量值是由实际使用的 min()决定的(记住,一个函数的两种用法是调
用它和取它的地址。)。类型和值的替换过程被称为模板实例化(template instantiation )。我们将在下一节介
绍模板实例化。
当一个名字被声明为模板参数之后,它就可以被使用了,一直到模板声明或定义结束为止。模板类型
参数被用作一个类型指示符,可以出现在模板定义的余下部分。它的使用方式与内置或用户定义的类型完
全一样,比如用来声明变量和强制类型转换。模扳非类型参数被用作一个常量值,可以出现在模板定义的
余下部分。它可以用在要求常量的地方,或许是在数组声明中指定数组的大小或作为枚举常量的初始值。
在函数模板定义中声明的对象或类型不能与模板参数同名:
template <class Type>
Type min(Type a,Type b)
{
//错误:重新声明模板参数 Type
typedef double Type;
Type tmp = a < b ? a : b;
Return tmp;
4
}
模板类型参数名可以被用来指定函数模板的返回位:
//ok: T1 表示 min ( )的返回类型
//T2 和 T3 表示参数类型
template <class T1, class T2, class T3>
T1 min(T2,T3);
模板参数名在同一模板参数表中只能被使用一次。例如,下面代码就有编译错误:
//错误:模板参数名 Type 的非法重复使用
template <class Type, class Type>
Type min(Type,Type);
但是,模板参数名可以在多个函数模板声明或定义之间被重复使用:
//ok:名字 Type 在不同模板之间重复使用
template <class Type>
Type min(Type,Type);
template <class Type>
Type max(Type,Type);
如果一个函数模板有一个以上的模板类型参数,则每个模板类型参数前面都必须有关键字 class 或
typename。
//ok:关键字 typename 和 class 可以混用
template<typenameT,class U>
T minus(T*,U);
//错误:必须是<typenameT,class U>或<typenameT,typename U>
template<typename T,U>
T sum(T* , U);
在函数模板参数表中,关键字 typename 和 class 的意义相同,可以互换使用。它们两个都可以被用来
声明同一模板参数表中的不同模板类型参数。看起来,好像用 typename 而不是 class 来指派模板类型参数
更为直观,毕竟,关键字 typename 名字能更清楚地表明后面的名字是个类型名。但是,关键字 typename
是最近才被加入到标准 C++中的。
2、函数模板实例化
函数模板指定了怎样根据一组或更多实际类型或值构造出独立的函数。这个构造过程被称为模板实例
化(template instantiation )。这个过程是隐式发生的,它可以被看作是函数模板调用或取函数模板的地址的
副作用。例如,在下面的程序中,min()被实例化两次:一次是针对 5 个 int 的数组类型,另一次是针对 6
个 double 的数组类型。
5
【例 15.1】求数组元素中最小值的函数模板。
//函数模板 min()的定义,有一个类型参数 Type 和一个非类型参数 size
template<typename Type,int size>
Type min(Type (&r_array)[size])
{
Type min_val = r_array[0];
for(int i=1;i<size;i++)
{
if(r_array[i] < min_val)
{
min_val = r_array[i];
}
}
return min_val;
}
void main()
{
int ia[] = {10,7,14,3,25};
double da[6] = {10.2,7.1,14.5,3.2,25.0,115.8};
//用数组 ia 实例化 min()
//Type=>int, size=>5
int i = min(ia);
cout<<"integer min() worked:"<<i<<endl;
//用数组 ia 实例化 min()
//Type=>double, size=>6
double d = min(da);
cout<<"double min() worked:"<<i<<endl;
}
注意:本例请在
VS2005
编译器中调试,
VC++6
下无法通过。
运行 int i=min(is); ,被实例化为下面的 min()的整型实例,这里 Type 被 int, size 被 5 取代:
int min(int (&r_array) [5])
{
int min_val = r_array[0];
for(int i=1;i<size;i++)
{
if(r_array[i] < min_val)
{
min_val = r_array[i];
}
}
return min_val;
}
类型参数 Type 和非类型参数 size 都被用作函数参数。为了判断用作模板实参的实际类型和值,编译
器需要检查函数调用中提供的函数实参的类型。在我们的例子中,ia 的类型(即 5 个 int 的数组)和 da 的类
型(即 6 个 double 的数组)被用来决定每个实例的模板实参。用函数实参的类型来决定模板实参的类型和值
剩余37页未读,继续阅读
JANE_JANE_
- 粉丝: 2
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0