泛类编程
学习模板,首先我们需要了解一下什么是泛类编程
#include<iostream>
using namespace std;
int add(int a, int b)
{
return a + b;
}
double add(double a, double b) //这两个add构成了函数重载
{
return a + b;
}
int main()
{
int a = 1;
int b = 2;
double c = 3;
double d = 4;
cout << add(a, b) << endl;
cout << add(c, d) << endl;
//假如我们想要实现不同类型变量的相加,可以创建不同的函数,构成函数重载来分别调用不同的函数
return 0;
}
我们可以使用c++的函数重载来解决这个问题,但是函数重载本身就存在问题
1、函数重载仅仅类型不同,假如出现了新的类型,我们就需要重新写新的函数重载,代码的利用率低
2、代码可维护性低,一个出错可能会导致所有函数重载出错
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段
所以c++提供了一种模板来解决这个问题
模板本质上:本来应该由你写的代码,然后不想重复写,你给了一个模板,编译器通过模板,帮你生成了对应的代码
函数模板
函数模板的概念
函数模板代表了一个函数家族,该函数模板与实参无关,当函数被使用时候会被实参初始化,从而产生不同的函数类型
函数模板的使用
函数模板的格式:
template<typename T1, typename T2, ......, typename Tn> //函数模板的参数不止一个,可以有很多参数
//返回值类型 函数名(参数列表) {}
函数模板的使用:
template<typename T> //也可以用<class T>,效果和<typename T>一样,但是不能用struct
T add(T x, T y)
{
return x + y;
}
注意:typename是函数模板的关键字,也可以使用class,但是不能使用struct
函数模板的实例化
当我们用不同的参数使用函数模板时,就称为函数模板的初始化
函数模板的实例化有两种:
1、隐式实例化(让编译器根据实参推演模板参数的实际类型)
#include<iostream>
using namespace std;
template<typename T>
T add(T x, T y)
{
return x + y;
}
int main()
{
int a = 1, b = 2;
double c = 3, d = 4;
cout << add(a, b) << endl; //使用了隐式实例化,由编译器自动推演实例化参数类型
return 0;
}
2. 显式实例化(在函数名后的<>中指定模板参数的实际类型)
#include<iostream>
using namespace std;
template<typename T>
T add(T x, T y)
{
return x + y;
}
int main()
{
int a = 1, b = 2;
double c = 3, d = 4;
cout << add<int>(a, c) << endl;
//由于a和c的类型不同,所以我们必须使用显示实例化,即函数名后面<type>括号中加上你想要实例化的类型
return 0;
}
函数模板的匹配原则
1、模板模板可以和一个同名非函数模板同时存在
2、假如模板函数和非模板函数同名,编译器会选择一个更匹配的类型进行使用
#include<iostream>
using namespace std;
int add(int x, int y)
{
return x + y;
}
template<typename T>
T add(T x, T y)
{
return x + y;
}
int main()
{
int a = 1, b = 2;
double c = 3, d = 4;
cout << add(a, b) << endl; //因为a,b是整型,所以会调用非函数模板,因为有都是整型参数的非函数模板
return 0;
}
3、模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
#include<iostream>
using namespace std;
template<typename T>
T add(T x, T y)
{
return x + y;
}
int main()
{
int a = 1, b = 2;
double c = 3, d = 4;
cout << add(a, (int)c) << endl;
return 0;
}
假如我们要使用函数模板的add,需显示实例化add,或者将c强制类型转换,函数模板不会自动转换,因为他不知道要如何转换的
类模板
类模板的定义格式
类模板的定义格式:
template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};
template<class T> //创建类模板
class Date
{
public:
void init();
private:
int _year;
};
template<class T> //假如我们需要在类模板的类外面定义函数,需要添加模板列表
Date<int>init() //还需要在类名后面<>中添加模板参数列表
{
_year = 0;
}
类模板的实例化
//Date是类名,Date<int>是类型
Date<int> d; //类模板的实例化需要在类模板名的后面<>中添加想要实例化的类型
到此这篇关于c++分离讲解模板的概念与使用的文章就介绍到这了,更多相关c++模板内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!