C++ 模板
C++ 中模板可以实现 参数化多态性 这一特性
参数化多态性: 程序所处理的对象的类型参数化,使一段程序可用于处理多种不同类型的对象
C++ 中的模板类型包括:函数模板 和 类模板
模板不能直接使用,需要对象类型确定后,才能生成 模板函数 或 模板类 来使用,这就是 实例化 过程
函数模板
函数模板的定义形式:
template<模板参数表>
类型名 函数名(参数表)
{
函数体定义
}
其中模板参数表由用逗号分隔的 模板参数 构成,包括:
- typename(或class)标识符,指明可以接收一个类型参数 (感觉用的多一点)
- ”类型说明符“ 标识符,指明可以接收一个”类型说明符“常量作为参数
- template<参数表>class 标识符,指明可以接收一个类模板名作为参数
实例:
#include<iostream>
using namespace std;
//模板定义
template<typename T>
T abs(T x){
return x<0?-x:x;
}
//模板使用
int mian(){
int n = -5;
double d = -5.5;
n = abs(n);
d = abs(d);
cout << n << d <<endl;
return 0;
}
函数模板定义实例:
template<class T>
void outputArray(const T* array, int count){
for (int i=0; i<count; i++)
cout<<array[i]<<" ";
cout<<endl;
}
函数模板的定义其实和普通函数的定义差不多,就是用类型参数代替确定的类型来定义函数
注意:
- 函数模板本身编译时不生成目标代码,模板实例化时才生成目标代码
- 函数模板最好连同函数体和声明一起放在头文件里面
- 函数指针只指向模板实例,不指向模板本身
类模板
使用类模板使用户可以为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数,返回值或局部变量能取任意类型(包括系统预定义的和用户自定义的)
-
类是对一组对象的共有性质的抽象
-
类模板是对不同类的公共性质的
-
抽象类模板是属于更高层次的抽象
类模板的声明形式:
template<模板参数表>
class 类名{
类成员声明
}
类成员声明和普通类差不多,就是用类型参数代替确定的类型
在类模板外定义其成员函数,采用的形式:
template<模板参数表>
类型名 类名<模板参数标识符列表>::函数名(参数表)
使用模板类创建对象,采用的形式:
模板名<模板参数表> 对象名1,对象名2,....,对象名n;
实例:
#include <iostream>
#include <cstdlib>
using namespace std;
struct Student { //结构体Student
int id; //学号
float gpa; //平均分
};
template<class T> //类模板:实现对任意数据类型的存取
class Store {
private:
T item; //item用于存放任意类型数据
bool haveValue; //标记item是否已被存入内容
public:
Store(); //默认无参构造
T &getElem(); //提取数据函数
void putElem(const T &x); //存入数据函数
};
//以下实现各成员函数
template<class T>
Store<T>::Store():haveValue(false) {}
template<class T>
T &Store<T>::getElem() {
if(!haveValue) { //如果试图提取未初始化的数据,则终止程序
cout<<"No item present!"<<endl;
exit(1);
}
return item; //返回item中存放的数据
}
template<class T> //存入数据函数的实现
void Store<T>::putElem(const T &x) {
haveValue = true; //将haveValue置为true,表示已存入数据
item = x;
}
int main() {
Store<int>s1,s2; //定义两个Store<int>类对象
s1.putElem(3);
s2.putElem(-7);
cout<<s1.getElem()<<" "<<s2.getElem()<<endl;
Store<Stdent>s3; //定义一个Store<Student>类对象
Student g={1000,23};
s3.putElem(g);
cout<<"The sudent id is "<<s3.getElem().id<<endl;
return 0;
}