为什么须要模板?

我们已经学过重载(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. 6-Java-C(移动距离)

    题目描述: X星球居民小区的楼房全是一样的,并且按矩阵样式排列.其楼房的编号为1,2,3... 当排满一行时,从下一行相邻的楼往反方向排号. 比如:当小区排号宽度为6时,开始情形如下: 1  2  3 ...

  2. rtim() 函数说明

    rtim() 函数 string rtrim ( string $str [, string $character_mask ] ) 该函数删除 str 末端的空白字符(或者其他字符)并返回. 不使用 ...

  3. mysql 修改表的字段

    修改一个表的字段 ALTER TABLE `member` CHANGE `memberid` `memberid` bigint unsigned; 修改含有外键的字段 -- 执行 begin 到 ...

  4. CAD使用DeleteXData删除数据(com接口)

    主要用到函数说明: MxDrawEntity::DeleteXData 删除扩展数据,详细说明如下: 参数 说明 pzsAppName 删除的扩展数据名称,如果为空,删除所有扩展数据 c#代码实现如下 ...

  5. Android网站

    http://blog.csdn.net/airsaid/article/details/52902299 android调用传感器的代码 http://blog.csdn.net/huangbiao ...

  6. java线程池 多线程搜索文件包含关键字所在的文件路径

    文件读取和操作类 import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; publi ...

  7. 多线程之Java中的等待唤醒机制

    多线程的问题中的经典问题是生产者和消费者的问题,就是如何让线程有序的进行执行,获取CPU执行时间片的过程是随机的,如何能够让线程有序的进行,Java中提供了等待唤醒机制很好的解决了这个问题! 生产者消 ...

  8. jquery.guide.js 新手指引

    /*! * by xyb * 新版上线时候的黑色半透明镂空遮罩指引效果实现jQuery小插件 * 兼容到IE8+ * MIT使用协议,使用时候保留版权 * */ $.guide = function ...

  9. 微信小程序UI组件库 iView Weapp快速上手

    概述 今天在网上突然看到iView新出了一个微信小程序的组件库iView Weapp,自己就上手试了一下,发现用起来还是不错的,把自己使用的过程与大家分享下. 一 预览iView组件 1.可以在手机上 ...

  10. python 安装模块 更新模块

    #显示模块pip list #显示过期模块pip list --outdated #安装模块pip install xxx #升级模块pip install --upgrade xxx