前言:本教程使用到的工具是vs2010;

目录

为什么要使用模板?

template模板

函数模板

类的模板

template模板的本质

总结


为什么要使用模板?

我们先来大概了解一下模板的概念,下面是菜鸟教程对于模板给出的解释:

模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。

模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。

每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 vector <int> 或 vector <string>

知道了模板的基本概念之后,我们先来看一段代码:

#include <stdio.h>
#include <Windows.h>void Sort(int* arr, int nLength)
{int ii;int kk;for(ii=0;ii<nLength-1;ii++){for(kk=0;kk<nLength-1;kk++){if(arr[kk]>arr[kk+1]){int temp  = arr[kk];arr[kk]   = arr[kk+1];arr[kk+1] = temp;}}}
}int main()
{return 0;
}

这是一段最简单的冒泡排序代码,看不懂没关系,知道怎么用就行;

继续往下:

我们定义一个整型数组,里面存放被打乱了的几个整数,如下:

然后我们调用函数,如下:

调试:

此时顺序是乱的,单步步过F10一下:

已经重新排序;

好了,我们现在知道这个函数怎么用了,继续往下看:

我们知道在C语言中'a'和'b'是可以比较的,因为字符类型其实也就是整型,他们的比较是ascii码值的比较,'a'的ascii码值是97,'b'的是98,'c'的99....以此类推,那么我们是不是可以对字符进行排序呢?

可以;

我们复制一下上面的整形冒泡排序代码,改一点就行了,如下:

我们定义一个字符数组,并进行排序,如下:

调试:

单步F10:

排序成功!

虽然我们达到了目的,但是我们违背了面向对象编程设计思想: 提高代码的复用性,减少重复代码的编写;

        但是,template模板可以帮我们解决这个问题,这也就是我们为什么要使用模板的原因了;

template模板

        template模板又分为函数模板和类模板,我们先讲函数模板;

        函数模板

函数模板的格式:

template<class 形参名,形参名,......>

返回值类型 函数名(参数列表)

{

函数体;

}

下面我们给我们的冒泡排序函数加上模板:

!!!!注意看图片上的文字!!!!;

        然后把我们想要自适应类型的地方全部换成T就行了,如下:

下面我们来测试,先测试int类型,如下:

调试:

F10:

没有问题,接着我们测试char类型:

调试:

F10:

没有问题;

        那么这个函数能对自己定义的类型进行排序吗?

        当然可以;

        如下,我们定义一个类:

我们首先要知道,如果我们想给我们自己定义的类的对象进行排序的话,那么我们肯定要进行运算符重载;

我们观察一下刚刚冒泡排序的函数,需要比较类的对象大小的地方有哪些:

我们可以发现,就这一个地方需要对我们类的对象进行比较大小,而且是大于号;

        那么我们只需要重载'>'即可,如下:

下面我们进行测试,定义对象,并调用模板函数:

调试:

F10:

ok,没有问题;

template模板成功的帮我们减少了重复代码的编写,提高了代码的复用性;

类的模板

先看代码:

#include <stdio.h>
#include <Windows.h>template<class T>
class CBase
{
public:int  x;int  y;char a;char b;int MAX(){if(x>y) return x;if(x<y) return y;}char MIN(){if(a>b) return b;if(a<b) return a;}
};int main()
{return 0;
}

定义了一个类,类中有四个成员变量;分别是int型的x、y;char型的a、b;

然后x和y比较谁大返回谁,a和b比较谁小返回谁;

我们来分析一下,这个类中大概有几个需要自适应类型的地方:

我们知道了这个类中大概有两个地方需要自适应类型,那么接下来先声明这个类为模板类:

因为我们有两个需要自适应的类型,所以这里的class参数有两个;

下面我们进行模板的替换:

替换好了,下面我们进行测试:

定义好对象以后,我们给对象的成员进行赋值:

我们调用比较的成员函数:

我们将鼠标悬停到MAX和MIN上:

可以看到,在我们CBase<int, char>声明之后,编译器就已经知道MAX和MIN函数的类型了;我们接收一下返回值,如下:

观察r和t:

没有问题;

当然在类中的模板中,也是可以比较类的对象的,依旧需要重载运算符,这里我就不演示了;

template模板的本质

下面我们来说一下,template模板的本质:

代码如下:

#include <stdio.h>
#include <Windows.h>class CBase
{
public:int x;int y;CBase(int x,int y){this->x = x;this->y = y;}bool operator>(CBase& right)      // 因为我们'>'有两个操作数,左是this指针,那么这里的右操作数只能传一个参数;{return this->x > right.x && this->y > right.y;            // 返回左操作数大于右操作数的结果,如果左大于右就为真,否则为假,达到了大于号的目的;}
};template<class T>               // 只需要在这里加上模板声明即可
void Sort(T* arr, int nLength)
{int ii;int kk;for(ii=0;ii<nLength-1;ii++){for(kk=0;kk<nLength-1;kk++){if(arr[kk]>arr[kk+1]){T temp  = arr[kk];arr[kk]   = arr[kk+1];arr[kk+1] = temp;}}}
}int main()
{int   arr1[5] = {2,1,4,5,3};char  arr2[5] = {'c','b','d','a','e'};CBase c1(2,2),c2(1,1),c3(4,4),c4(3,3),c5(5,5);CBase arr3[5] = {c1,c2,c3,c4,c5};Sort(arr1,5);            // 此处下断点system("pause");return 0;
}

首先我们先对arr1进行排序,断点下载Sort;编译、调试、alt+8转到反汇编,如下:

template模板在底层已经识别了改排序是int类型的排序,这没有问题;

然后我们将arr2也假如排序,那么template底层会怎么做呢?

编译、调试、alt+8反汇编:

可以看到template模板在底层又重新生成了一个函数,用于char类型的排序;

那么arr3如果加入排序的话,相比大家也都知道结果了,这里我就不测试了;感兴趣的话可以自己测试一下;

现在我们可以总结一下template的本质是什么了;

template模板并没有我们想的那么高大上,就是说仅仅一个函数可以千变万化,其实并不是千变万化也并不是一个函数;

我们刚刚也看到了,模板的底层就是通过看你传入参数的类型,给你分配一个适用你传入类型的函数,你传入int类型,他就给你一个适用int类型的函数,你传入char他就给你一个适用char类型的函数;如果你连续传入int、char等n个类型进行排序,那么他的底层就会给你分配n个函数,并不是一个函数实现的类型自适应;

总结

1、我们使用模板的目的就是为了提高代码的复用性,减少重复代码的编写;

2、函数模板的底层并不是只有一个函数完成的,它是根据你传入参数的类型,给你分配一个适用你传入类型的函数;如果你连续传入n个类型,他就会给你分配n个函数;

结语:

文章讲义到此结束,如果有讲错的地方或者说讲的不好的地方,望指出;感谢大家观看!

【C++】模板template相关推荐

  1. C++中的模板template

    1.Cpp中的模板template 模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码.模板是创建泛型类或函数的蓝图或公式.库容器,比如迭代器和算法都是泛型编程的例子,它们都使用了 ...

  2. playbook核心元素之 模板template 介绍(7)

    playbook核心元素之 --> 模板template 介绍 templates:文件文件,内部嵌套有模板语言脚本(使用模板语言编写) [root@ansible ~]# ansible-do ...

  3. python string模块template_Python - 定制pattern的string模板(template) 详解

    定制pattern的string模板(template) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/28625179 s ...

  4. vue 模板 html 表达式,Vue 模板template、指令directive、修饰符

    模板 template template的三种写法 写法一:Vue完整版,写在HTML里 //html {{n}} +1 //vue new Vue({ el: '#xxx', data(){ ret ...

  5. C++:18---函数模板(template)

    一.模板的定义 template<typename T> 以关键字template开头,后面跟一个模板参数列表,列表里面用逗号将多个模板参数隔开定义的注意事项 模板的编译 当编译器遇到一个 ...

  6. C++类模板template <class T>简单使用方法

    一个简单的例子 两个数比大小 如果两个数都是int类型 class Compare_int { public :Compare(int a,int b){x=a;y=b;}int max( ){ret ...

  7. C++ 使用模板Template

    template --声明创建模板I typename -- 表面其后面的符号是一种数据类型,可以用class代替 T --- 通用的数据类型,名称可以替换,通常为大写字母 使用模板之前: #incl ...

  8. 设计模式学习笔记——模板(Template)模式

    设计模式学习笔记--模板(Template)模式 @(设计模式)[设计模式, 模板模式, template, 模板方法] 设计模式学习笔记模板Template模式 基本介绍 模板案例 类图 实现代码 ...

  9. Vue2 模板template的四种写法总结

    下面小编就为大家分享一篇Vue2 模板template的四种写法总结,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. 如下所示: <div ...

  10. C++ 模板template

    模板template 模板是对具有相同特性的函数或类的再抽象,模板是一种参数多态性的工具,可以为逻辑功能相同而类型不同的程序提供一种代码共享的机制. 一个模板并非一个实实在在的函数或类,仅仅是一个函数 ...

最新文章

  1. remote_port java_Java HttpServletRequest.getRemotePort方法代碼示例
  2. 【Android 逆向】Android 进程注入工具开发 ( 总结 | 源码编译 | 逆向环境搭建使用 | 使用进程注入工具进行逆向操作 ) ★★★
  3. (一)网络与信息安全概论入门阶段笔记
  4. java对象在内存中的布局
  5. 如何使用单例EJB和MBean构建和清除参考数据缓存
  6. windows 2012 powershell 创建Ad
  7. (转)ORACLE之常用FAQ V1.08
  8. 软件开发常用英文词汇
  9. Spring底层原理问题
  10. ArcGIS ERROR 999999: 执行函数时出错,未找到表。
  11. 金士顿内存条真假测试软件,金士顿内存条真伪怎么看?金士顿内存条判别真伪的几种方法...
  12. VUE:element ui组件应用之个人中心页面
  13. 一些好用的APP推荐给你
  14. 光流传感器 定位精度_光流传感器其它方面的应用
  15. 投资高手三十年投资经验总结的18条真谛
  16. 微软sus服务器搭建,规划和部署 Exchange Server
  17. Ms Sql Server 2000 个人绿色版 5.62
  18. js vue汉字转拼音或拼音首字母
  19. 毕业设计 树莓派人脸识别系统(Python)
  20. 如何查看win7计算机的显卡是多少位的,如何查看咱们win764位旗舰版电脑是单显卡还是双显卡...

热门文章

  1. Python 浮点数计算出十几位小数的解决方法
  2. HashMap红黑树原理解析
  3. 华为手机计算机的隐藏功能,后悔现在才发现,华为手机一个隐藏功能,人人都想要却不知道...
  4. Winbond W25Qxx SPI FLASH 使用示例(基于沁恒CH32V307单片机)
  5. Bomb Lab!!!
  6. 如何查看到chrome缓存真实的内容?
  7. 暑假第九天之每天一些题系列
  8. 大数据技能立异才能显著提升使用场景日益多元
  9. 基于windows server 2008r2配置server-U服务器
  10. NandFlash操作详解(一)