1.函数模板
函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。
1.1函数模板的定义:
template<类型形式参数表>
返回类型 函数名(形式参数表)
{
… //函数体
}
template // or class T
void Swap(T &a, T &b);
或者:
template //
void Swap(T &a, T &b);
(I):一个函数模板可以有多个类型参数
template<class T1, class T2>
void print(T1 arg1, T2 arg2){
//函数体
}
(II):函数模板的类型参数可以用于函数体模板的局部变量声明
template<class T1, class T2>
void print(T1 arg1, T2 arg2){
T1 locVar=arg1;
//函数体
}
1.2实例
// funtemp.cpp -- using a function template
#include <iostream>
// function template prototype
template <typename T> // or class T
void Swap(T &a, T &b);
int main()
{
using namespace std;
int i = 10;
int j = 20;
cout << "i, j = " << i << ", " << j << ".\n";
cout << "Using compiler-generated int swapper:\n";
Swap(i, j); // generates void Swap(int &, int &)
cout << "Now i, j = " << i << ", " << j << ".\n";
double x = 24.5;
double y = 81.7;
cout << "x, y = " << x << ", " << y << ".\n";
cout << "Using compiler-generated double swapper:\n";
Swap(x, y); // generates void Swap(double &, double &)
cout << "Now x, y = " << x << ", " << y << ".\n";
// cin.get();
system("pause");
return 0;
}
// function template definition
template <typename T> // or class T
void Swap(T &a, T &b)
{
T temp; // temp a variable of type T
temp = a;
a = b;
b = temp;
}
2.函数模板的重载
同一函数名,类型参数的数量不同。
需要对多个不同类型使用同一种算法的函数时,重载函数模板。被重载的模板的函数的特征标(模板类型参数列表)必须不同。
2.1实例
// twotemps.cpp -- using overloaded template functions
#include <iostream>
template <typename T> // original template
void Swap(T &a, T &b);
template <typename T> // new template
void Swap(T *a, T *b, int n);
void Show(int a[]);
const int Lim = 8;
int main()
{
using namespace std;
int i = 10, j = 20;
cout << "i, j = " << i << ", " << j << ".\n";
cout << "Using compiler-generated int swapper:\n";
Swap(i, j); // matches original template
cout << "Now i, j = " << i << ", " << j << ".\n";
int d1[Lim] = { 0,7,0,4,1,7,7,6 };
int d2[Lim] = { 0,7,2,0,1,9,6,9 };
cout << "Original arrays:\n";
cout << "d1[8]: " << endl;
Show(d1);
cout << "d2[8]: " << endl;
Show(d2);
Swap(d1, d2, Lim); // matches new template
cout << "After Swapping arrays:\n";
cout << "d1[8]: " << endl;
Show(d1);
cout << "d2[8]: " << endl;
Show(d2);
// cin.get();
return 0;
}
template <typename T>
void Swap(T &a, T &b)
{
T temp;
temp = a;
a = b;
b = temp;
}
template <typename T>
void Swap(T a[], T b[], int n)
{
T temp;
for (int i = 0; i < n; i++)
{
temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
void Show(int a[])
{
using namespace std;
for (int i = 0; i < Lim; i++)
cout << a[i]<<" ";
cout << endl;
}
运行结果:
3.类模板
I.为了多快好省地定义一批相似的类,可以先定义类模板,然后由类模板生成不同的类(即模板类)。
II.在定义类的时候给它一个或者多个参数,这个/些参数表示不同的数据类型。
III.在调用类模板时,指定参数,由编译系统根据参数提供的数据类型自动产生相应的模板类。
3.1类模板的定义
template<class T1, class T2>//一个或者多个类型参数
class MyclassTemplateName{
//成员函数和成员变量
}
类模板的参数声明中可以包括非类型参数:
非类型参数用来说明类模板中的某些属性,而类型参数则是用来说明类模板中的属性类型,成员服务的参数类型和返回值类型。通常,类模板参数声明中的非类型参数可以提高程序的执行效率。
template<class T1,class T2,int size>
class PairKV{
//成员函数和成员变量
}
同函数模板一样,类型参数表中的关键字class可以用typename,此处class并不是表示一个类类型,可以用基本数据类型进行实例化。
类模板的成员函数拿到类外定义语法如下:
template<class T1,class T2>
return_valueType MyclassTemplateName<class T1,class T2>::myfunction(参数列表){
//函数体
}
用类模板定义对象的写法如下:
MyclassTemplateName<真实类型参数表>对象名(构造函数实际参数表);
MyclassTemplateName<真实类型参数表>对象名; //无参构造函数
3.2实例
#include <iostream>
#include<string>
using namespace std;
//define classTemplate
template<class T1,class T2>
class PairKV {
public:
T1 key;//index
T2 value;// value
PairKV(T1 k, T2 v) :key(k), value(v) {};
};
int main(){
PairKV<string, int>student("Tom",20 );//实例化一个对象
cout << student.key << " " << student.value << endl;
return 0;
}
4.模板类的概念
I.模板类—–为类模板中各类型参数指定了具体的数据类型后,即得到了一个模板类。
(1)编译系统自动用具体的数据类型替换类模板中的类型参数,生成模板类的代码。
(2)为类型参数指定的数据类型不同,得到的模板类不同。也就是说一个类模板可以生成很多种不同的模板类。
II.模板类=实例化的类模板
5.类模板的产生
(1)直接定义
(2)类模板从其他类模板派生
(3)类模板从其他模板类派生
(4)类模板从普通类派生