C++学习笔记-模板
函数模板与模板函数
函数模板是一类功能大概相同的函数的模板, 模板函数是根据这个模板具体实现的函数
声明一个模板的具体格式
template <class ElemType>//Elemtype是元素类型
ElemType Max(ElemType x, ElemType y) // 求x,y的最大值
{
return x < y ? y : x; // 返回x,y的最大值
}
使用函数模板生成模板函数有两种声明方法
1.函数模板名(实参表) 例如Max(2, 3), 这个时候默认是int型的变量, 但不能Max(2, 3.0),这样编译器无法分辨具体的数据类型
2.函数模板名<类型>(实参表) 既可以Max(2, 3), 也可以Max(2, 3.0)(编译器会自动转换)
模板函数类似于重载函数,但是同一个函数模板类型形式参数具体化(实例化)后的所有模板函数必须执行相同的代码,而函数重载时在每个函数体中可以执行不同的代码,当遇到执行的代码有所不同时,不能简单地套用函数模板,而应像重载普通函数那样进行重载
当既有重载函数模板也有函数模板时,编译器首先匹配类型完全相同的重载函数,如果匹配失败,再寻求函数模板进行匹配 ;此机制称为模板特化和偏特化(部分特化)
示例
//重载函数模板与匹配过程示例。
template <class ElemType>
ElemType Max(ElemType x, ElemType y) // 求x,y的最大值
{
return x < y ? y : x; // 返回x,y的最大值
}
//模板特化
char *Max(char *str1, char *str2) // 求str1,str2的最大值
{
return strcmp(str1, str2) < 0 ? str2 : str1;// 返回str1,str2的最大值
}
int main()
{
cout << "2和3的最大值为" << Max(2, 3) << endl;
// 输出2,3的最大值, 匹配函数模板
cout << "China与American的最大值为"
<< Max("China", "American") << endl;
// 输出"China","American"的最大值, 匹配函数
}
类模板与模板类
模板类的声明格式
template <class ElemType>
class Array
{
private:
// 数据成员
ElemType *elem; // 存储数据元素值
int size; // 数组元素个数
public:
// 公有函数
Array(int sz): size(sz) { elem = new ElemType[size]; } // 构造函数
~Array(){ delete [] elem; } // 析构函数
void SetElem(ElemType e, int i); // 设置元素值
ElemType GetElem(int i) const; // 求元素值
};
类模板中函数的声明既可以在类中也可以在类外定义, 在类内定义时与普通类定义差别不大, 在类外定义时的格式如下:
template <class ElemType>//首先声明是模板类的函数
void Array<ElemType>::SetElem(ElemType e, int i) // 类名界定符也要声明是模板类, 元素属性未确定
{
if (i < 0 || i >= size)
{
cout << "元素位置错!" << endl;
exit(1); // 退出程序的运行,返回到操作系统
}
elem[i] = e; // 设置元素值为e
}
template <class ElemType>
ElemType Array<ElemType >::GetElem(int i) const // 求元素值
{
if (i < 0 || i >= size)
{
cout << "元素位置错!" << endl;
exit(2); // 退出程序的运行,返回到操作系统
}
return elem[i]; // 返回元素值elem[i]
}
重载函数调用运算符()
C++规定函数调用运算符**()只能重载为类的成员函数**,具体声明格式如下:
返回值类型 operator()(形参表)
重载函数调用运算符()的用途是使类的对象可以象函数名称一样使用, STL中称为仿函数或函数对象。运算符()是通过用户自定义对象来调用函数,也就是用户自定义对象是第一个操作数
在声明类模板的类型形参表中还可以包含常规参数,常规参数经常是数值。
示例
template <class ElemType, int size>
class Array
{
private:
// 数据成员
ElemType elem[size]; // 存储数据元素值
public:
void SetElem(ElemType e, int i); // 设置元素值
ElemType GetElem(int i) const; // 求元素值
};