模板
模板是C++封装特性的体现,利用模板能够将多个功能类似的函数或类封装起来同一管理。C++提供两种模板机制:函数模板和类模板
函数模板
函数模板是将多个实现相同的函数抽象为一个模板的一种技术,利用函数模板能简化代码。如,一个交换函数,利用普通函数重载会因重复性代码过多造成冗余,利用函数模板的特性就能将多个交换函数封装成一个加法函数模板,进而简化代码。值得一提的是,C++中的STL库大部分的函数都是利用函数模板来实现的,因此学习函数模板的使用能够让我们更快熟悉STL库内函数的使用。
函数模板的使用
如图所示,调用函数模板存在两种方法,分别为 自动类型推导 和 显示指定类型,两种方法均可调用对应的模板,但有些特殊情况需要单独处理,后面会具体分析。
自动类型推导:不加模板参数列表,直接调用该函数。
template<class T>
void Swap(T& x, T& y)
{
T temp = x;
x = y;
y = temp;
}
int a = 10;
int b = 20;
Swap(a, b);//自动类型推导
显示指定类型:加模板参数列表,并指明函数参数类型。
template<class T>
void Swap(T& x, T& y)
{
T temp = x;
x = y;
y = temp;
}
char c = 'c';
char d = 'd';
Swap<char>(c, d);//显示指定类型
1.普通函数与函数模板
1.1.普通函数可自动类型转换,函数模板直接调用无法自动类型转换,显示调用可以发生自动类型转换。
1.2.普通函数和函数模板均支持缺省参数,其中函数模板的模板参数列表中类型也可缺省。
1.3.函数模板支持函数重载,当普通函数与函数模板相同,默认调用普通函数,也可利用模板参数列表强制调用函数模板。
2.函数模板的特性
模板实例化:函数模板在调用时会根据传入的参数类型创建对应的函数实例。这种过程叫做模板实例化。
函数模板调用时机:函数模板的所有实现均在编译阶段生成,仅创建被调用的版本,以避免造成内存浪费。
3.函数模板的限制
3.1.默认调用无法进行隐式类型转换需要显示指定类型。
3.2.若调用类型过多会导致编译时间过长,内存占用膨胀。
以上是函数模板的所有内容,事实上主要是掌握好函数模板与普通函数调用的区别即可,掌握后也就更好操作后续的STL库函数了。
类模板
所谓类模板,简单来说就是传入参数后可以创建不同的类,从而实现多个类的封装。本节主要掌握类模板与普通类的区别以及如何调用模板类来实例化对象。在C++STL中也是大量运用到类模板来实现各种类型的数据结构,在实际开发过程中为了更好地使用STL中的数据类型我们就得清楚地认识到类模板的调用及实例化对象等操作。
类模板的实现
我们知道,普通类有各种语法。例如,继承,友元,内部类等等。值得一提的是,这些语法基本上都能在类模板中使用,只是使用的方式会和普通类有些区别,本节会涉及到一些该方面的内容。但并不是重点,重点是要能掌握使用类模板的方式,以便后续能熟练操作STL库内的类模板。
1.类模板与普通类
1.1.类模板的模板参数列表支持缺省参数
注意,即使缺省参数后可以不填类型但仍要用空列表来调用该类模板来实例化对象。
1.2.普通类与类模板不可同名同时存在
1.3.类模板中的成员函数在被调用时才创建,普通类中的成员函数一开始就创建。
1.4.类模板对象做函数参数
我们知道类模板可以创建对象,那么当使用该对象作为函数参数传递会与普通类实例化出的对象有何不同呢?主要传递方式有以下三点:
1.指定传入类型。
2.参数模板化。
3.整个类模板化。
上面三种方式其实最常用的是第一种直接指定传入类型,实际上将参数模板化和整个类模板化都是结合了函数模板来实现的,目的是以适应传入不同的类型,但适得其反导致调用过程更加繁琐了,因此一般实际过程中都用直接指定传入类型即可。
类模板与继承
类模板支持继承的语法,但与普通类稍有不同。首先总结一下,类模板的继承主要有三种方式,类模板继承类模板,类模板继承普通类以普通类继承类模板。下面分别讲解提到的三种方式之间的区别
类模板继承类模板:
注意:当子类模板继承父类模板时,应当在子类的模板参数列表中指明继承下来的父类类型,以便在子类中直接使用,原因是继承下来的父类属性的类型是未知的,在子类调用时也要连带父类的一起赋值。
普通类继承类模板:
类模板继承普通类:
总结:如果子类继承的父类时一个类模板时,子类在声明时要指出父类中的类型,否则无法为子类分配内存;如果子类也是类模板,则无需指明父类类型,但依然要在子类模板参数列表中用一个符号来代指父类的通用类型,以方便子类使用。
类模板与友元
在普通类中,友元有三种,分别为:全局函数做友元、类作友元以及成员函数做友元。本节重点讲解全局函数做友元,另外两个暂不做讲解,因为涉及到一些编译链接的知识,讲太多会偏题,而且也基本不会怎么用类模板来使用友元。
全局函数做友元:
以上就是类模板的所有内容了,学习类模板的主要目的不是创建类模板来写代码而是知道该如何使用和调用STL库中的类模板。