1 泛型编程介绍
泛型是指具有在多种数据类型上皆可以操作含义。在C++中,为了对类型的封装,引入泛型编程
概念。STL(标准模板库)是典型的泛型编程
2 泛型编程的分类
通常分为两种:函数模板和类模板
函数模板是一种特殊的函数,可通过不同类型来进行调用 ,而函数模板是C++中重要的代码复用方式。
语法格式:
函数模板中的类型指定方式:
template <typename T>
template <class T>
T 它代表的是泛型,大家已经习惯使用T,也可以使用其他字符
template typename class 都是关键字
语法:
template <typename 类型参数表>
返回类型 函数模板名(函数参数列表)
{
函数模板体
}
//如果一个函数的实现,只有类型不同,而其他的内容都一样,那么建议使用函数 模板
template <typename T> //告诉编译器T 是一个泛型,不能报错
void Swap(T&a ,T&b)
{
T temp = a;
a = b;
b = temp;
}
//它的能力只管当前的函数,如果下一个函数要使用模板,要重新声明
template <typename T,class T1>
void printT(const T&a ,const T1&b)
{
cout << "a = " << a << "b = " << b << endl;
}
int main()
{
float a = 3;
float b = 4;
cout << a << " " << b << endl;
//对于函数模板而言,对于泛型的指定是两种方式:通过实参的类型来自动推导 ,还可以通过函数调用时,显示指定
Swap(a,b); // 自动推导
Swap<float>(a,b); //显示指定
cout << a << " " << b << endl;
return 0;
}
3 函数模板与函数重载
函数模板也是函数的一种,它也可以进行函数重载
template <typename A>
A mymax(A a,A b)
{
cout << "fuction : A mymax(A a,A b)"<<endl;
return a>b?a:b;
}
//重载
template <typename A>
A mymax(A a,A b, A c)
{
cout << "fuction : A mymax(A a,A b, A c)"<<endl;
return mymax(mymax(a,b),c);
}
template <typename A,typename B>
A mymax(A a,B b)
{
}
int main()
{
cout << mymax(5,6);
cout << mymax(5,6,7);
return 0;
}
总结:
1. 当函数模板和普通函数都符合调用时,优先选择普通函数
2. 若显示使用函数模板,则在调用函数是使用<类型列表>
3.如果函数模板有更好的匹配,优先选择函数模板
4.函数模板在调用时,可以显示或者隐式调用
4 编译器对模板机制的分析 :
temp1ate <typename T>void funcc(T c)
{
cout << c<<end1 ;
}
//编译器在编译函数模板时,要进行二次编译
//第一次编译时,确定该函数是一个函数模板---定义一个函数的模子
//在调用函数时--->func2
//再次编译,根据传输的参数或者显示指定的泛型,将模子具体变成一个函数
//funcc(1) --->函数如下:
void funcc(int c)
{
cout <<c<<end1 ;
}
funcc(0. 5); —-->
void funcc(f1oat c){
cout << c<<end1 ;
}
总结:
1.编译器并不是将函数模板处理成能处理任意类型的函数
2.编译器从函数模板通过具体类型产生不同函数
3.编译器会对函数模板进行二次编译,在声明的地方对模板进行代码的基本和语法进行编译 ,在调用的地方对参数替换后的代码再进行编译