【C++】模板template
前言:本教程使用到的工具是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相关推荐
- C++中的模板template
1.Cpp中的模板template 模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码.模板是创建泛型类或函数的蓝图或公式.库容器,比如迭代器和算法都是泛型编程的例子,它们都使用了 ...
- playbook核心元素之 模板template 介绍(7)
playbook核心元素之 --> 模板template 介绍 templates:文件文件,内部嵌套有模板语言脚本(使用模板语言编写) [root@ansible ~]# ansible-do ...
- python string模块template_Python - 定制pattern的string模板(template) 详解
定制pattern的string模板(template) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/28625179 s ...
- vue 模板 html 表达式,Vue 模板template、指令directive、修饰符
模板 template template的三种写法 写法一:Vue完整版,写在HTML里 //html {{n}} +1 //vue new Vue({ el: '#xxx', data(){ ret ...
- C++:18---函数模板(template)
一.模板的定义 template<typename T> 以关键字template开头,后面跟一个模板参数列表,列表里面用逗号将多个模板参数隔开定义的注意事项 模板的编译 当编译器遇到一个 ...
- C++类模板template <class T>简单使用方法
一个简单的例子 两个数比大小 如果两个数都是int类型 class Compare_int { public :Compare(int a,int b){x=a;y=b;}int max( ){ret ...
- C++ 使用模板Template
template --声明创建模板I typename -- 表面其后面的符号是一种数据类型,可以用class代替 T --- 通用的数据类型,名称可以替换,通常为大写字母 使用模板之前: #incl ...
- 设计模式学习笔记——模板(Template)模式
设计模式学习笔记--模板(Template)模式 @(设计模式)[设计模式, 模板模式, template, 模板方法] 设计模式学习笔记模板Template模式 基本介绍 模板案例 类图 实现代码 ...
- Vue2 模板template的四种写法总结
下面小编就为大家分享一篇Vue2 模板template的四种写法总结,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. 如下所示: <div ...
- C++ 模板template
模板template 模板是对具有相同特性的函数或类的再抽象,模板是一种参数多态性的工具,可以为逻辑功能相同而类型不同的程序提供一种代码共享的机制. 一个模板并非一个实实在在的函数或类,仅仅是一个函数 ...
最新文章
- remote_port java_Java HttpServletRequest.getRemotePort方法代碼示例
- 【Android 逆向】Android 进程注入工具开发 ( 总结 | 源码编译 | 逆向环境搭建使用 | 使用进程注入工具进行逆向操作 ) ★★★
- (一)网络与信息安全概论入门阶段笔记
- java对象在内存中的布局
- 如何使用单例EJB和MBean构建和清除参考数据缓存
- windows 2012 powershell 创建Ad
- (转)ORACLE之常用FAQ V1.08
- 软件开发常用英文词汇
- Spring底层原理问题
- ArcGIS ERROR 999999: 执行函数时出错,未找到表。
- 金士顿内存条真假测试软件,金士顿内存条真伪怎么看?金士顿内存条判别真伪的几种方法...
- VUE:element ui组件应用之个人中心页面
- 一些好用的APP推荐给你
- 光流传感器 定位精度_光流传感器其它方面的应用
- 投资高手三十年投资经验总结的18条真谛
- 微软sus服务器搭建,规划和部署 Exchange Server
- Ms Sql Server 2000 个人绿色版 5.62
- js vue汉字转拼音或拼音首字母
- 毕业设计 树莓派人脸识别系统(Python)
- 如何查看win7计算机的显卡是多少位的,如何查看咱们win764位旗舰版电脑是单显卡还是双显卡...