【C++】模板template
创始人
2024-01-21 18:30:15
0

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

目录

为什么要使用模板? 

template模板

        函数模板

        类的模板

template模板的本质 

总结


为什么要使用模板? 

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

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

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

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

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

#include 
#include void Sort(int* arr, int nLength)
{int ii;int kk;for(ii=0;iiarr[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

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

        {

                函数体;

        }

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

 

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

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

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

 

        调试:

 

        F10:

 

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

 

        调试:

 

        F10:

         

        没有问题;

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

        当然可以;

        如下,我们定义一个类:

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

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

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

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

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

 

        调试:

 

        F10:

 

        ok,没有问题;

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

        类的模板

        先看代码:

#include 
#include template
class CBase
{
public:int  x;int  y;char a;char b;int MAX(){if(x>y) return x;if(xb) return b;if(a

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

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

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

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

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

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

 

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

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

 

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

 

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

 

 

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

        观察r和t:

 

        没有问题;

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

template模板的本质 

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

        代码如下:

#include 
#include 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				// 只需要在这里加上模板声明即可
void Sort(T* arr, int nLength)
{int ii;int kk;for(ii=0;iiarr[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个函数;

结语:

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

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...