《C++从入门到精通》实例--模板
目录
1 什么是模板
模板是实现代码重用机制的一种工具,它可以实现类型参数化,即吧类型定义为参数,从而实现代码的可重用性。而且模板能够减少源代码量并提高代码的机动性,而不会降低类型安全。
C++程序由类和函数组成,模板也分为类模板和函数模板。模板就是把功能相似、仅数据类型不同的函数或类设计为通用的函数模板或类模板,提供给用户。
模板是“泛型编程”的基础,所谓泛型编程就是用独立于任何特定类型的方法编写代码。所以简单地说,类是对象的抽象,而模板是类的抽象,用模板能定义出具体类。
2 模板的语法
2.1 函数模板
函数模板的一般定义形式是:
template <class 或typename T> 返回类型 函数名 (函数形参表)
{
//函数定义体
}
模板定义以关键字template开始,后接模板形参表,模板形参表是用尖括号括住的一个或多个模板形参的列表。形参由关键字class或template及其后面的标识符构成,形参之间以逗号分隔。注意,当模板类型参数有多个时,每个模板类型参数的前面都必须有关键字class或template,例如:
template<typename T,U> 错误
template<typename T,class U> 或 template<typename T,typename U> 正确
用模板定义max()函数来求两个数中的较大者:
template<typename T>
T max(T a, T b) //比较两个任一类型的参数,返回较大者
{
return a > b ? a : b;
}
关键字typename 和class有什么区别?
在模板定义中,两者意义相同,可以互换使用,甚至可以在同一模板形参表中存在。但关键字typename是作为标准C++的组成部分加入到C++中的,因此旧的程序更有可能只用关键字class。
2.2 类模板
类模板的一般定义形式如下:
template <class T>
class 类名
{
//类定义
};
例如定义一个类模板,用来存储两个任意类型的元素:
template <class T> //类模板声明
class pair //类名
{
T value1, value2; //类成员变量
public:
pair(T first, Tsecond)
{
value1 = first;
value2 = second;
}
};
//如果我们想定义该类的一个对象,用来存储两个整型数据24和101,则:
pair <int> myobject(24, 101);
如果要在类模板之外定义它的一个成员函数,就必须在每一个函数前面加template <class T>。若此成员函数中有模板参数T存在,则需要在函数体外进行模板声明,并且在函数名前类名后缀上“T”。
比如我们想定义一个成员函数getmax()获取数对中的较大值:
template <class T> //类模板声明
pair<T>::getmax()
{
return value > value2 ? value1 : value2; //比较并返回较大值
}
3 实例说明
3.1 函数模板
//范例1:定义一个函数模板,比较两个相同数据类型的参数的大小
//知识点:函数模板
//2018.4.29
#include <iostream>
using namespace std;
template <typename T> T max(T x, T y)
{
return x > y ? x : y;
}
int main(int argc, char* argv[])
{
int n1 = 4, n2 = 13;
double d1 = 3.5, d2 = 7.9;
cout << "较大整数" << max(n1, n2) << endl;
cout << "较大实数" << max(d1, d2) << endl;
return 0;
}
范例分析:
程序中首先定义了一个函数模板max(T x,T y),但这并不是一个实实在在的函数,编译器不会为其产生任何可执行代码。该定义只是对函数的描述,表示它每次能单独处理在类型形式参数表中说明的数据类型。
当编译器发现一个函数调用max(n1,n2)时,则根据实参表中的类型int,先生成一个重载函数:
int max(int x, int y)
{
return x > y ? x : y;
}
该重载函数的定义体与函数模板的函数定义体相同,而形参表的类型则以实参表的实际类型为依据。该重载函数称为模板函数。由函数模板生成模板函数的过程称为函数模板的实例化。
函数模板和模板函数是什么关系?
函数模板是模板的定义,是模板函数的抽象,定义中要用到通用类型参数。
模板函数是实实在在的函数定义,是函数模板的实例,它由编译系统在碰见具体的函数调用时所生产,具有程序代码,占用内存空间。
3.2 类模板
//范例1:使用类模板,接受两个不同类型的变量并显示
//知识点:类模板
//2018.4.29
#include <iostream>
using namespace std;
template<typename T1, typename T2>
class myClass
{
private:
T1 a;
T2 b;
public:
myClass(T1 x, T2 y)
{
a = x;
b = y;
}
void show()
{
cout << "a=" << a << ",b=" << b << endl;
}
};
int main(int argc, char* argv[])
{
myClass<int, int> obj1(6, 12);
obj1.show();
myClass<int, double> obj2(6, 2.12);
obj2.show();
return 0;
}