C++中的模板功能介绍
.前言C++中的模板分为函数模板和类模板。在C++中,模板允许我们处理问题的逻辑从不同的数据类型中抽离出来,形成容器和算法。当我们需要对某种数据进行存取和处理的时候,我们可以在程序中,选择合适的模板指定我们需要的数据类型,这个时候,编译器就会为我们生成适合这种类型的容器和算法函数。.函数模板1、情景多个一样或几乎完全一样的重载函数体带来的问题不仅是冗余,还有就是当你打算修改算法的时候,如果你没有在
.前言
C++中的模板分为函数模板和类模板。
在C++中,模板允许我们处理问题的逻辑从不同的数据类型中抽离出来,形成容器和算法。
当我们需要对某种数据进行存取和处理的时候,我们可以在程序中,选择合适的模板指定我们需要的数据类型,这个时候,编译器就会为我们生成适合这种类型的容器和算法函数。
.函数模板
1、情景
多个一样或几乎完全一样的重载函数体带来的问题不仅是冗余,还有就是当你打算修改算法的时候,如果你没有在各个函数体里进行同步修改的话,还会造成在同一系统中,处理同类型的问题,用的算法不一致,导致不一致性的问题。
2、例子
问题:整数类型和浮点数类型求绝对值的十分,需要写两种重载函数吗?
int abs(int x)
{
return x < 0 ? -x : x;
}
double abs(double x)
{
return x < 0 ? -x : x;
}
//两函数体相同,仅参数类型不同,产生冗余
解决办法:函数模板
功能:
(1)可用来创建动态增长和减小的数据结构
(2)它是类型无关的,因此具有很高的可复用性。
(3)它在编译时而不是运行时检查数据类型,保证了类型安全
(4)它是平台无关的,可移植性
(5)可用于基本数据类型
template<typename T>
T abs(T x)
{
return x < 0 ? -x : x;
}
//编译器根据实参类型,推导出类型(简单理解为在调用时用对应类型的标识符代替)
3、定义
函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。
4、格式
函数模板定义语法
.语法形式:
template<模板参数表>
函数定义
.模板参数表的内容
.类型参数:class(或typename)标识符
.常量参数:类型说明符 表示符
模板参数:template<参数表> class 标识符
.类模板
1、类模板的作用
使用类模板使用户可以为类声明一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值,能取任意类型(包括基本基本类型和用户自定义类型)
2、格式
类模板:
template<模板参数表>
class 类名
{
类成员声明
}
如果需要在类模板以外定义其函数,则要采取以下的形式:
template<模板参数表>
类型名 类名<模板参数标识符列表>::函数名(参数名)
例:
#include <iostream>
using namespace std;
struct Student
{
int id; //学号
float gpa; //平均分
};
template<class T>
class Store//类模板:实现对任意数据进行存取
{
public:
Store();
T& getElem(); //提取数据函数
void putElem(const T& x); //存入数据函数
private:
T item; //item用于存放任意类型的数据
bool haveValue; //haveValue标记item是否已被存入内容
};
//函数实现
//定义Store()
template <class T>
Store<T>::Store():haveValue(false){}
//定义getElem()
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,表示item中已存入数值
haveValue = true;
item = x; //将x值存入item
}
int main()
{
Store<int> s1, s2;//此时整型int代替T,可简单理解为有个函数Store<数据类型>,会把之前暂未定义的数据类型给替代为<>中的数据类型
s1.putElem(3);
s2.putElem(-7);
cout << s1.getElem() << " " << s2.getElem() << endl;
Student g = { 1000,23 };
Store<Student> s3;
s3.putElem(g);
cout << "The student id is" << s3.getElem().id << endl;//s3.getElem返回了Student类型
Store<double> d;
cout << "Retrieving object D...";
cout << d.getElem() << endl;
//d未初始化,执行函数D.getElement()时导致程序终止
return 0;
}
结果为:
3 -7
The student id is1000
Retrieving object D...No item present!
注:
c++模板类/模板函数的声明与定义应该放在头文件里,不要分开来写类中函数的声明与定义(比如在.H文件里声明某个成员函数,在.CPP文件里定义该成员函数),这样会导致连接错误。所应该将模板类/模板函数的定义与声明写在一个.h文件里。(如果你用VS给的提示也是让你在头文件定义)
更多推荐
所有评论(0)