为什么须要模板?

我们已经学过重载(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. CAD参数绘制线型标注(网页版)

    主要用到函数说明: _DMxDrawX::DrawDimRotated 绘制一个线型标注.详细说明如下: 参数 说明 DOUBLE dExtLine1PointX 输入第一条界线的起始点X值 DOUB ...

  2. LPCTSTR 字符串获取其长度

    LPCTSTR lpStr = "123456789";int i=CString(lpStr).GetLength();

  3. java_String类练习

    public class StringTest { //1.模拟trim方法,去除字符串两端的空格 public static void main(String[] args) { String st ...

  4. pytorch笔记:09)Attention机制

    刚从图像处理的hole中攀爬出来,刚走一步竟掉到了另一个hole(fire in the hole*▽*) 1.RNN中的attentionpytorch官方教程:https://pytorch.or ...

  5. python3.x Day5 subprocess模块!!

    subprocess模块: # subprocess用来替换多个旧模块和函数 os.system os.spawn* os.popen* popen2.* commands.* subprocess简 ...

  6. assert.notStrictEqual()详解

    严格不相等测试,由不全等运算符确定(===). const assert = require('assert'); assert.notStrictEqual(1, 2); // OK assert. ...

  7. Linux 文件与目录结构

    [Linux文件] Linux 系统中一切皆文件. [Linux目录结构] --/bin 是Binary的缩写, 这个目录存放着最经常使用的命令. --/sbin s就是Super User的意思,这 ...

  8. 分享大牛开发经验,浅谈java程序员职业规划

    在中国有很多人都认为IT行为是吃青春饭的,如果过了30岁就很难有机会再发展下去!其实现实并不是这样子的,在下从事.NET及JAVA方面的开发的也有8年的时间了,在这...... 在中国有很多人都认为I ...

  9. 慕课笔记利用css进行布局【一列布局】

    <html> <head> <title>一列布局</title> <style type="text/css"> bo ...

  10. Leetcode 139.单词拆分

    单词拆分 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词. 说明: 拆分时可以重复使用字典中的单词. 你可以假设字典 ...