一.泛型编程
- 不考虑具体数据类型的编程方式
- 泛型编程的意义:泛型编程就是为了代码复用! 是C++中重要的代码复用方式
例:如何实现通用的swap函数
void swap(int& left, int& right) {
int temp;
temp = left;
left = right;
right = temp;
}
不难想到,用一个通用的模子。具体调用时,再对其进行物料填充。这就引出了模板。
模板:
- 函数模板
- 类模板
二.函数模板
1.概念:函数模板代表了一个函数家族,该函数模板与数据类型无关。在使用时被参数化,根据实参类型产生特定类型的实体函数。
- 是一种特殊的函数可以用不同类型进行调用
- 看起来和普通函数很相似,区别是不被数据类型所局限。
2.函数模板格式:
template<typename t1,typename t2 .....>//关键字template typename 数据类型t1 t2。。。。
解决通用swap函数
template <typename t1>
void swap(t1 left, t1 right) {
t1 temp;
temp = left;
left = right;
right = temp;
}
具体调用函数模板实例:
#include<iostream>
using namespace std;
template <typename t1>
void swap(t1 left, t1 right) {
t1 temp;
temp = left;
left = right;
right = temp;
}
int main() {
swap<int>(1, 2.0);//隐式调用
//swap(2,3.0); //会报错。没有匹配类型
swap<int>(1, 2.0);//解决方案 显式调用 如果显式类型不匹配,会隐式调用
system("pause");
return 0;
}
定义任意多个不同的类型参数
#include<iostream>
using namespace std;
template < typename T1, typename T2, typename T3 >
T1 Add(T2 a, T3 b)
{
return (T1)(a + b);
}
int main() {
int r1 = Add<int>(0.5, 0.8);
int r2 = Add<int, float>(0.5, 0.8);
int r3 = Add<int, float, float>(0.5, 0.8);
system("pause");
return 0;
}
- 对于多参数函数模板,无法自动推导返回值类型,所以在工程中将返回值作为第一个类型参数 返回值类型必须显式指定。
3.模板函数底层实现:在编译阶段,编译器通过形参类型来推演生成对应类型的函数。以供调用。
4.其他注意事项:
- 1.可以存在同名的函数模板与非函数模板
- 2.相同条件下,优先调用非函数模板。
- 3.模板函数不允许类型转换,普通函数是允许的。
- 4.显式调用时,调用函数模板
三.类模板
1.类模板格式:与函数模板相同
template <typename t1>
class A {
public:
t1 add() ;
private:
t1 _a;
int _b;
};
template <typename t1> //在类外定义成员函数必须加模板参数列表
t1 A<t1>:: add() {
return (t1)_a + _b;
}
int main() {
A <int> d1;
system("pause");
return 0;
}
2.注意事项
- 只能进行显式创建
- 在类外定义成员函数必须加模板参数列表