为什么须要模板?

我们已经学过重载(Overloading),对重载函数而言,C++ 通过函数參数(參数个数、參数类型)的正确匹配来调用重载函数。比如。为求两个数的最大值,我们定义 max () 函数须要对不同的数据类型分别定义不同重载(Overload)版本号。

//函数1
int max(int x, int y);
{
return(x>y)? x:y ;
} //函数2
float max( float x, float y)
{
return (x>y)? x:y ;
} //函数3
double max(double x, double y)
{
return (c>y)?x:y ;
}

如今。我们再又一次审视上述的 max() 函数,它们都具有相同的功能,即求两个数的最大值,是否能仅仅写一套代码解决问题呢?这样就会避免因重载函数定义不全面而带来的调用错误(如。我们分别定义了 char a,b; 那么在运行 max(a,b) 时 程序就会出错,由于我们未定义char 类型的重载版本号)。

相同的,对于类而言,也存在相同的问题(基本上是反复性的工作):

//对两个整数作比較
class Compare_int
{
public:
Compare(int a,int b){x=a;y=b;}
int max( ) {return(x>y)?x:y;}
int min( ) {return(x<y)? x:y;}
private:
int x,y;
}; //对两个浮点数作比較
class Compare_float
{
public:
Compare(float a,float b) {x=a;y=b;}
float max( ) {return(x>y)?x:y;}
float min( ) {return(x<y)? x:y;}
private:
float x,y;
}

为解决上述问题 C++ 引入模板机制:模板就是实现代码重用机制的一种工具,它能够实现类型參数化,即把类型定义为參数。 从而实现了真正的代码可重用性。模版能够分为两类。一个是函数模版。另外一个是类模版。

函数模板

函数模板的一般形式例如以下:

template <class 形參名, class 形參名, ……> 返回类型 函数名(形參表)

{

//函数定义体

}

当中 template 和 class 是keyword,class 能够用 typename 取代,在这里 typename 和 class 没差别。<> 括号里的參数叫模板形參。模板形參和函数形參非常相像。模板形參不能为空。

一但声明了类模板,函数中使用内置类型的地方都能够使用模板形參名来声明

模板形參须要调用该模板函数时提供的模板实參来初始化模板形參,一旦编译器确定了实际的模板实參类型就称他实例化了函数模板的一个实例。

template <class T> void swap(T& a, T& b)
{
//……
}

当调用这种模板函数时类型 T 就会被被调用时的类型所取代,比方 swap(a,b) 当中 a 和 b 是 int  型,这时模板函数 swap 中的形參 T 就会被 int 所取代,模板函数就变为 swap(int &a, int &b)。而当 swap(c,d) 当中 c 和 d 是 double 类型时,模板函数会被替换为swap(double &a, double &b),这样就实现了函数的实现与类型无关的代码。

演示样例代码例如以下:

#include <iostream>
using std::cout;
using std::endl; //声明一个函数模版,用来比較输入的两个同样数据类型的參数的大小,
//class也能够被typename取代。
//T能够被不论什么字母或者数字取代。 //template <typename T>
template <class T> T max(T x,T y)
{
return(x>y)?x:y;
} int main()
{ int a=2, b=10;
cout<< "较大整数:"<<max(a, b)<<endl; double m=1.5, n=5.6;
cout<< "较大实数:"<<max(m, n)<<endl; return 0;
}

执行结果例如以下:

类模板

类模板的一般形式例如以下:

template <class 形參名, class 形參名, ……>   class 类名

{

//类定义...

};

一但声明了类模板就能够用类模板的形參名声明类中的成员变量和成员函数,即能够在类中使用内置类型的地方都能够使用模板形參名来声明。比方:

template <class T> class A
{
public:
T a;
T b;
T hy(T c, T &d);
};

在类 A 中声明了两个类型为T的成员变量 a 和 b。还声明了一个返回类型为 T 带两个參数类型为 T 的函数 hy。

类模板对象的创建:比方一个模板类 A,则使用类模板创建对象的方法为 A<int> m;在类 A 后面跟上一个 <> 尖括号并在里面填上对应的类型。这种话类 A 中凡是用到模板形參的地方都会被 int  所取代。

当类模板有两个模板形參时创建对象的方法为 A<int, double> m;类型之间用逗号隔开。

在类模板外部定义成员函数的方法为:

template<模板形參列表> 函数返回类型 类名<模板形參名>::函数名(參数列表){函数体}

比方有两个模板形參 T1。T2 的类 A 中含有一个 void h() 函数。则定义该函数的语法为:

template<class T1, class T2> class A
{
public:
void h();
}; template<class T1,class T2> void A<T1,T2>::h()
{
// ……
}

注意:模板的声明或定义仅仅能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比方不能在 main() 函数中声明或定义一个模板。

演示样例代码例如以下:

#include <iostream>
using namespace std; template <class numtype> class Compare //类模板
{
public:
//Compare(numtype a,numtype b){x=a;y=b;}
Compare(numtype a,numtype b);
numtype max(){return (x>y)?x:y;}
numtype min(){return (x<y)? x:y;}
private:
numtype x,y;
}; template <class numtype> Compare<numtype>::Compare(numtype a,numtype b)
{
x=a;
y=b;
} int main( )
{
Compare<int>cmp1(3,7); //定义对象cmp1,用于两个整数的比較
cout << cmp1.max() << " is the Maximum" << endl;
cout << cmp1.min() << " is the Minimum" << endl << endl; Compare<float> cmp2(45.78,93.6); //定义对象cmp2。用于两个浮点数的比較
cout << cmp2.max() << " is the Maximum" <<endl;
cout << cmp2.min() << " is the Minimum" <<endl<<endl; Compare<char> cmp3('a', 'A'); //定义对象cmp3。用于两个字符的比較
cout << cmp3.max() << " is the Maximum" <<endl;
cout << cmp3.min() << " is the Minimum" <<endl; return 0;
}

执行结果例如以下:

本教程演示样例代码下载请点此处。

參考资料:

http://www.cnblogs.com/gw811

http://www.cnblogs.com/gaojun

C++入门学习——模板的更多相关文章

  1. Elasticsearch7.X 入门学习第八课笔记-----索引模板和动态模板

    原文:Elasticsearch7.X 入门学习第八课笔记-----索引模板和动态模板 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接: ...

  2. opengl入门学习

    OpenGL入门学习 说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640 ...

  3. ReactJS入门学习一

    ReactJS入门学习一 阅读目录 React是什么? React如何制作组件? 理解组件属性props 理解页面中如何渲染数据的 理解从服务器端获取数据及理解state的 回到顶部 React是什么 ...

  4. OpenGL入门学习(转)

    OpenGL入门学习 http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 说起编程作图,大概还有很多人想起TC的#includ ...

  5. OpenCV入门学习笔记

    OpenCV入门学习笔记 参照OpenCV中文论坛相关文档(http://www.opencv.org.cn/) 一.简介 OpenCV(Open Source Computer Vision),开源 ...

  6. Egg入门学习(二)---理解service作用

    在上一篇文章 Egg入门学习一 中,我们简单的了解了Egg是什么东西,且能做什么,这篇文章我们首先来看看官网对Egg的整个框架的约定如下,及约定对应的目录是做什么的,来有个简单的理解,注意:我也是按照 ...

  7. OpenGL入门学习(转载)

    说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色 ...

  8. JavaSE入门学习21:Java面向对象之接口(interface)(二)

    一接口实现的多态 在上一篇博文:JavaSE入门学习20:Java面向对象之接口(interface)(一)中提到了接口的实现存在多态性,那么 这一篇主要就要分析接口实现的多态. 实例一 Test.j ...

  9. 反射实现Model修改前后的内容对比 【API调用】腾讯云短信 Windows操作系统下Redis服务安装图文详解 Redis入门学习

    反射实现Model修改前后的内容对比   在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责. 首先我们要创建一个User类 1 p ...

随机推荐

  1. shellinabox的安装使用

    一.简介 Shell In A Box(发音是shellinabox)是一款基于Web的终端模仿器,由Markus Gutschke开辟而成.它有内置的Web办事器,在指定的端口上作为一个基于Web的 ...

  2. java_线程分类

    线程分为守护线程和用户线程,如java虚拟机的回收机制就是守护线程,线程开始运行它就启动,线程结束它就结束 用户线程变守护线程:Thread(线程).setDaemon(true)

  3. 08C#事件

    C#事件 1.2      事件 事件是C#语言内置的语法,可以定义和处理事件,为使用组件编程提供了良好的基础. 1.16.1       事件驱动 Windows操作系统把用户的动作都看作消息,C# ...

  4. python 获取路径

    获取目录路径和文件路径 import osfor root, dirs, files in os.walk(".", topdown=False): # ‘.’为获取脚本所在路径下 ...

  5. vue 自定义指令使用

    <template> <div> <!-- 让input元素在打开页面的时候就获得焦点 --> <input type="text" v- ...

  6. 大项目之网上书城(七)——书页面以及加入购物车Servlet

    目录 大项目之网上书城(七)--书页面以及加入购物车Servlet 主要改动 1.shu.jsp 代码 效果图 2.shu.js 代码 3.index.jsp 代码 效果图 4.FindBookByC ...

  7. MongoDB安装与配置启动

    1.下载安装包.mongodb-linux-x86_64-rhel62-3.6.3.tgz 2.解压.修改名字. 3.修改配置文件: # mongodb.conf #where to loglogpa ...

  8. linux中PHP安装扩展包(mongodb为例)

    相对于windows中的PHP扩展,只需要在下载相应的dll资源,并且添加配置在php.ini之后即可. 但是在linux安装扩展时,需要进行编译安装. 这里以lnmp一键安装包为例(php.ini位 ...

  9. 90-Standard Deviation 标准离差指标.(2015.7.4)

    Standard Deviation 标准离差指标 ~计算: StdDev = SQRT (SUM (CLOSE - SMA (CLOSE, N), N)^2)/N 注解: SQRT - 正方体根: ...

  10. Jbox 弹出窗口 子页面操作完成后关闭 父页面刷新

    父页面js //父页面js <script> var isFreshFlag = '1'; //添加会议活动 function addMeetingAct(){ var attendVip ...