【泛型编程】泛型编程让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。泛型即是指具有在多种数据类型上皆可操作的含义。(模板是泛型编程的基础)
模板:1.函数模板
2.类模板
【模板函数】:代表了一个函数家族,该函数与类型无关,在使用时被参数化,根据实参类型产生函数的 特定类型版本。(模板函数不是真正的函数)
实现一个通用的加法函数:
1.通过函数重载实现:
int Add(int left, int right)
{
return left + right;
}
char Add(char left, char right)
{
return left + right;
}
float Add(float left, float right)
{
return left + right;
}
double Add(double left, double right)
{
return left + right;
}
【Add函数实现重载】
优点:函数进行参数类型检测,自行调用与自身类型匹配的函数,调用方便且效率高。
缺点:1.只要有新类型出现,就要重新添加对应函数。
2.除类型外,所有函数的函数体都相同,代码的复用率不高。
3.如果函数只是返回值类型不同,函数重载不能解决。
4.一个方法有问题,所有的方法都有问题,不好维护
2.用函数模板实现
【模板函数的格式】
template
返回值类型 函数名(参数列表)
{ ... }
template
T Add(T left, T right)
{
return left + right;
}
int main()
{
cout << Add(1, 2) << endl; //3
cout << Add(1.1, 2.2) << endl; //3.3
cout << Add('1', '2') << endl; //c ('1'的ASCII为49,'2'的ASCII为50,两个之和为99是'c')
system("pause");
return 0;
}
内联函数是什么:
C++关键字,在函数声明或定义中函数返回类型前加上关键字inline,即可以把函数指定为内联函数。关键字inline必须与函数定义放在一起才能使函数成为内联,仅仅将inline放在函数声明前面不起任何作用。inline是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。一般的,用户可以阅读函数的声明,但是看不到函数的定义。
template
inline T Add(T left, T right)
{
return left + right;
}
模板函数特性
1.模板函数在运行时根据参数的类型来生成函。
2.模板函数内部,对代码不进行检测。
3.当有实参函数时,当先调用实参函数模板不会合成函数。
4.当有实参函数时,在调用模板时进行了显示实例化,则模板函数会合成函数进行调用。
【实参推演】
<从函数实参确定模板形参类型和值的过程称为模板实参推断
<多个类型形参的实参必须完全匹配
【类型形参转换】
一般不会转换实参以匹配已有的实例化,相反会产生新的实例。
编译器只会执行两种转换:
1、const转换:接收const引用或者const指针的函数可以分别用非const对象的引用或者指针来调用
2、数组或函数到指针的转换:如果模板形参不是引用类型,则对数组或函数类型的实参应用常规指 针转换。数组实参将当做指向其第一个元素的指针,函数实参当做指向函数类型的指针。
【模板函数的参数列表】
1.在函数模板的内部不能指定缺省的模板实参。
2.所有模板形参前面必须加上 class或者typename
3.模板形参可以是类型形参也可以是非类型形参
5、模板类型形参可作为类型说明符用在模板中的任何地方,与内置类型或自定义类型 使用方法完全相同,可用于指定函数形参类型、返回值、局部变量和强制类型转换
6、模板形参表中,class和typename具有相同的含义,可以互换,使用typename更加直观。 但关键字typename是作为C++标准加入到C++中的,旧的编译器可能不支持。
【模板函数重载】
模板函数重载与一般函数重载所需条件一样
1.作用域相同
2.函数名相同
3.参数列表不同
template
T Add(T left, N right)
{
return left + right;
}
template
T Add(T left,T& right)
{
return left + right;
}
template
T Add(N right, T left)
{
return left + right;
}
【模板函数特化】
有时候并不总是能够写出对所有可能被实例化的类型都合适的模板,在某些情况下,通用模板定 义对于某个类型可能是完全错误的,或者不能编译,或者做一些错误的事情。
当遇到这种比较字符串大小时,上面定义的模板函数无法合成正确的函数,在此我们可以把这种特殊情况重写一个函数,用来处理特殊的类型,
模板函数特化形式如下:
1.关键字template后面接< >
2.函数名后接模板名和< >,尖括号中指定这个特化定义的模板形参
3.函数形参表中形参的类型要与模板形参类型一致
函数格式
注意:在模板特化版本的调用中,实参类型必须与特化版本函数的形参类型完全匹配,如果不匹配,编译器将为实参模板定义中实例化一个实例。
注意:
特化不能出现在模板实例的调用之后,应该在头文件中包含模板特化的声明,然后使用该特化版本的每个源文件包含该头文件。