概念:
模板是泛型编程的基础,所谓泛型编程就是编写与类型无关的逻辑代码,是一种复用的方式。模板将类型定义为参数,从而实现了真正的代码可采用性
模板分为模板函数和模板类
一、模板函数
假设现在要实现一个比较俩个数是否相等的重载函数
int IsEqual(int a, int b)
{
return a == b;
}
bool IsEqual(const string& left, const string& right)
{
return left == right;
}
void Test()
{
string s1("s1"), s2("s2");
cout << IsEqual(s1, s2) << endl;
cout << IsEqual(1, 1) << endl;
}
如果还想实现char类型,double类型的比较俩个函数是否相等的函数,就要分别再写俩个,但是我们发现这些函数的功能基本一致,只是类型不同,所以我们就可以使用模板
模板的格式:
template<class 参数1,calss 参数2,class参数n>
返回值 函数名(参数列表)
{//……}
class也可以用typename代替,含义是相同的
下面我们来简单的实现一个模板函数:
template<typename T>
bool IsEqual(const T& left,const T& right)
{
return left == right;
}
void Test()
{
string s1("s1"), s2("s2");
cout << IsEqual(s1, s2) << endl;
cout << IsEqual(1, 1) << endl;
}
模板的调用过程:
用模板的时候我们最好使用引用,且加上const
模板参数匹配及显示实例化 :
我们发现一个参数是int,一个参数是double,这要调用函数是不行的。因为在调用一个模板函数时,编译器会根据参数的类型自动生成一个函数,而参数类型不一样时,编译器就不知道该自动生成哪种类型参数的函数。但是如果我们显示指定的话,编译器就会按照指定的类型去生成一个函数
函数名<类型>(参数列表);
要显示实例化,但是如果函数的参数是同一种类型可以不显示<int>,<double>
void Test()
{
cout<<IsEqual(1,1)<<endl;
//cout << IsEqual(1, 1.2) << endl;
cout << IsEqual<int>(1, 1.2) << endl;
cout << IsEqual<double>(1, 1.2) << endl;
}
但是这样调用的结果是不一样的,数据会根据类型进行转换:
二、模板类
1.模板类的形式:
template<class 形参1,class 形参2,class 形参n>
class 类名
{//…}
- 模板类和模板函数都是以template开始,后接模板形参列表组成。模板形参不能为空,一旦声明了类模板就可以用类模板的形参名声明类中的成员变量和成员函数。即使类中用内置类型的地方都可以使用模板形参来声明
template<class T>
class AA
{
public:
T _check(T a)
{}
private:
T _data;
}
该类中定义了一个类型为T的成员变量, 定义了一个返回值为T,参数为T的成员函数
最好不要在类中使用malloc,realloc,calloc,因为他们没有调用构造函数,容易出错
2.模板类对象的创建:
- 创建对象时,要在类名后加上<>,里面写清楚需要创建的类型。这样这个对象在使用的时候,类中凡是用到模板的地方都会被替换成<>中的类型。
- 模板类不存在实参类型的推断。
- 当模板类有多个模板时,创建对象要使用:类名<类型1,类型2> 对象名;中间用逗号隔开
- 一个模板类AA,在创建其对象时要使用:AA<int> a1; 如果BB有俩个模板时,创建其对象可以用BB<int,double> b;
template<typename T>
class AA
{
private:
T* _data;
};
template<typename P,typename V>
class BB
{
private:
P _a;
V _b;
};
void Test()
{
AA<int> a1;
BB<int, double> b1;
}
3.类外定义模板函数的方法:
template<模板形参列表>
函数返回值 类名<模板形参名>::函数名(参数列表)
{
//…
}
class AA
{
public:
void Print();
private:
T* _data;
};
void AA<int>::Print()
{
cout << _data << endl;
}
模板的优点:
- 模板复用了代码,节省资源,更快的迭代开发,c++的标准模板库(STL)因此而生
- 增强了代码的灵活性
模板的缺点:
- 模板让代码变得凌乱复杂,不易维护,编译代码时间变长
- 出现模板编译错误时,错误信息非常凌乱,不易定位错误