C++之模板

目录

泛型编程

模板

函数模板

函数模板的实例化

隐式实例化 

显示实例化

类模板


我们知道STL(标准模板库)是C++学习的精华所在,在学习STL之前我们得先学习一个新的知识点-------模板。那么模板究竟是什么呢?围绕着这个问题,进入我们本期的内容。

泛型编程

在学习模板之前我们得先了解什么是泛型编程?

大家可以先想想生活中的一个场景,比如说临近过年了,我们一般在大年夜要吃饺子,要吃饺子,饺子皮必然是必不可少的,比如要包100个饺子,一般情况下我们就得擀上100个饺子皮,但是这样是很费时间的,有没有什么好得方法呢?有人就想到了用一个圆形的模具,使用了圆形的模具之后,生成饺子皮的效率就高了很多了。

当然,上面的场景只是生活中的场景,我们来看看C++中的场景,比如说现在我们要进行两个数的交换,我们一般会写一个交换函数。假设这两个数的类型为int,char,double。相关的代码如下:

void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
void Swap(char& a, char& b)
{
	char tmp = a;
	a = b;
	b = tmp;
}
void Swap(double& a, double& b)
{
	double tmp = a;
	a = b;
	b = tmp;
}

我们发现上述三个交换函数就只有类型不同,其它的都是相同的,如果要交换的变量的类型很多时,难道我们也要写这么多的函数吗?有没有一种方法可以改变解决这种情景呢?在C语言中这种情景确实没有很好的解决办法,因为C语言是不支持泛型编程的,但是C++是支持泛型编程的,我们提出了模板这一概念,可以很好的解决这一情景带来的问题。

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。  

模板

模板分为函数模板和类模板。

注意:在函数中我们将函数括号中的参数称作形参,在函数模板这里我们将尖括号中的称作模板参数。

函数模板

函数模板:函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定 类型版本。

注意:在函数中我们将函数括号中的参数称作形参,在函数模板这里我们将尖括号中的称作模板参数。 

 所以对于上面交换三种类型变量的函数我们可以用函数模板实现,代码如下:

template<class T>  
void Swap(T& a, T& b)
{
	T tmp = a;
	a = b;
	b = tmp;
}
int main()
{
	int a = 10, b = 20;
	double c = 10.1, d = 9.3;
	char ch1 = 'a', ch2 = 'b';
	Swap(a, b);
	Swap(c, d);
	Swap(ch1, ch2);
	return 0;
}

 运行截图:

通过函数模板,不难发现,不同类型的变量确实发生了交换。

但是大家思考一个问题。这三次交换,调用的是同一个函数吗?我们通过底层代码为大家展现:

 很明显,这三次调用不是同一函数,因为函数参数列表的参数类型不同,函数的地址也是不同的。这其中到底发生了什么?

其实,这里发生了函数模板的实例化。我们将实参传给形参之后,编译器会根据我们实参的类型生成对应的函数模板,这相比之前我们手动实现函数,提高了效率。

函数模板的实例化

所谓函数模板的实例化,就是再调用函数模板时,编译器通过传递的实参的类型推导对应类型的函数,然后将实参传递给所推导的函数的形参。这就是函数模板的实例化。

隐式实例化 

隐式实例化:就是我们在调用函数模板时,编译器会根据我们传递的实参的类型自动推导函数模板中的模板参数类型。

注意:隐式实例化时,我们不能让传递的实参为两种类型,因为函数模板中只有一个模板参数,当模板参数只有一个时,一次函数调用只能实例化一种类型,这是如果传递了两种类型,就会报错。

对于两个数求和的代码: 

template<class T>
T  Add(T a, T b)
{
	return a + b;
}
int main()
{
	int a = 10, b = 20;
	double c = 10.1, d = 9.3;
	Add(a, d);
	return 0;
}

错误示例如下:

我们用了int,double两个类型的实参去调用函数模板,这是不行的。

要解决这种错误有两种方法,一种是类型强制类型转换,一种是显示实例化,告诉编译器模板参数类型。

显示实例化

显示实例化:在函数名后的<>中指明模板参数类型。

在进行函数模板的调用时,我们直接告诉编译器模板参数的类型。具体代码如下:

template<class T>
T Add(T a, T b)
{
	return a + b;
}
int main()
{
	int a = 10, b = 20;
	double c = 10.1, d = 9.3;
	Add(a, d);
	Add<int>(a, d);  //告诉编译器,模板参数的类型
	return 0;
}

类模板

我们为什么要引入类模板呢?

在我们学习栈时,我们学习栈一般是数组栈,栈的每个元素是有具体的类型的,但是如果我们想让栈的元素的类型灵活的变化,按照之前C语言的方式实现栈的话,我们可能得实现多个只有元素类型不同的栈(每次都用typedef定义不同的数据结构),会导致代码冗余,当然这只是针对相对空间较小栈,如果我们后期学习了一个相对空间很大的数据结构,如果再次碰到了这种情景,如果还是这样进行实现,就会导致大量资源的浪费,所以针对这种情况,C++的大佬们发明了类模板。我们依然以栈这个数据结构作为讲解,栈的类模板代码如下:

template<class T>
class Stack
{
public:
	Stack(int capacity=4)
		:_top(0)
		, _capacity(capacity)
	{
		_a = new T[capacity];
	}
	~Stack()
	{
		delete[] _a;
		_a = nullptr;
		_capacity = _top = 0;
	}
private:
	T* _a;
	int _Top;
	int _capacity;
};

int main()
{
	Stack<int> st1;
	Stack<double> st2;
	Stack<int*> st3;
    return 0;
}

注意:在之前我们类类型就是类名,但是在有了类模板之后,类类型就不再是类名了,此时也不能进行类模板的隐式实例化,只能进行类模板的显示实例化,所以此时的类类型就是类名<模板参数类型> 。此时我们创建对象不能再次使用类名创建对象,必须使用类名<模板参数类型> 创建对象

以上便是我们本期模板的所有内容,模板是学习STL的基础,小伙伴们一定要掌握模板的相关内容。

本期内容到此结束^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/247565.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java全栈体系结构-架构师之路(持续更新中)

Java 全栈体系结构 数据结构与算法实战&#xff08;已更&#xff09;微服务解决方案数据结构模型(openresty/tengine)实战高并发JVM虚拟机实战性能调优并发编程实战微服务框架源码解读集合框架源码解读分布式架构解决方案分布式消息中间件原理设计模式JavaWebJavaSE新零售电商项…

使用广播星历进行 GPS 卫星位置的计算

目录 1.计算卫星运动的平均角速度 n 2.计算观测瞬间卫星的近地点角 3.计算偏近点角 4.计算真近点角 f 5.计算升交角距 6.计算摄动改正项 7.进行摄动改正 8.计算卫星在轨道面坐标系中的位置 9.计算观测瞬间升交点的经度 L 10.计算卫星在瞬时地球坐标系中的位置 11.…

Matlab simulink PLL学习笔记

本文学习内容&#xff1a;【官方】2022小迈步之 MATLAB助力芯片设计系列&#xff08;一&#xff09;&#xff1a;电路仿真与模数混合设计基础_哔哩哔哩_bilibili 所用规格书&#xff1a;https://store.skyworksinc.com/datasheets/skyworks/sky73134_11.pdf 本文所用simulink…

【无标题】创新蓄势!安全狗多项技术获颁专利

近日&#xff0c;安全狗《一种网络安全监测方法、终端设备及存储介质》、《一种恶意进程风险等级评估方法、终端设备及存储介质》等多项专利顺利通过了国家知识产权局的相关审核认证&#xff0c;并获得了发明专利证书。 厦门服云信息科技有限公司&#xff08;品牌名&#xff1a…

Mistral AI发布开放权重的高质量SMoE模型Mixtral 8x7B

&#x1f989; AI新闻 &#x1f680; 开源MoE大模型震惊开源社区 摘要&#xff1a;上周末&#xff0c;Mistral开源了一款震惊开源社区的MoE大模型。MoE是一种神经网络架构设计&#xff0c;能够提升大语言模型的性能。通过使用MoE&#xff0c;每个输入token都可以动态路由到专…

【AutoDL】使用云服务器跑深度学习代码

一、AutoDL租用服务器 1.选用服务器 1.算力市场 租用服务器&#xff0c;选择自己心仪的服务器 2.镜像 可以选择一些基础的镜像&#xff0c;社区镜像里是git上有的环境。 3.上传文件 在文件存储中&#xff0c;选择上传的区&#xff0c;在右边点击上传&#xff0c;选择自己的文…

羊大师提问羊奶养胃,你知道吗?

近年来&#xff0c;人们对于健康的关注逐渐增加&#xff0c;养生已经成为一种时尚。养胃是其中一种重要的养生方式&#xff0c;而羊奶则是备受关注的一种养胃饮品。那么问题来了&#xff0c;羊奶真的能够养胃吗&#xff1f; 羊奶是一种营养丰富的乳制品&#xff0c;与牛奶相比…

记录 | docker报错could not select device driver ““ with capabilities: [[gpu]].

ubuntu18.04 上启动 docker start 报错&#xff1a; could not select device driver “” with capabilities: [[gpu]]. docker: Error response from daemon: could not select device driver “” with capabilities: [[gpu]]. ERRO[0005] error waiting for container: con…

如何在 JavaScript 中实现任务队列

任务队列的概念 任务队列就是存放任务的队列&#xff0c;队列中的任务都严格按照进入队列的先后顺序执行。 在前一条任务执行完毕后&#xff0c;立即执行下一条任务&#xff0c;直到任务队列清空。 任务队列的基本执行流程如下&#xff1a; 设置任务队列并发数&#xff1b; …

怎么制作GIF动图?教你这几个简单方法

怎么制作gif动图&#xff1f;GIF动图是一种非常有趣且实用的图片格式&#xff0c;它能够以短小精悍的方式展示动画效果&#xff0c;因此在社交媒体和聊天应用中备受追捧。本文将向您介绍几种制作GIF动图的方法&#xff0c;让您轻松制作出自己的动图。 GIF动图制作方法一&#x…

ubuntu pycharm 死机,如何重启

1. 找出pycharm 进程的id 进入命令行&#xff1a; ps -ef 是查看当前运行的进程 值输入 ps -ef 会返回所有当前执行的进程&#xff0c;太多了&#xff0c;过滤一下&#xff0c;找到 pycharm : ps -ef | grep pycharm 2. 使用 kill -s 9 来杀死进程 如图所是&#xff0c;…

WSL的导出与导入

1需求 现在我需要把我在平板上配好的系统导出来&#xff0c;再放到我的笔记本上。 2基本情况 笔记本电脑没装过wsl 平板上配好了wsl&#xff0c;并且里面的ubuntu配好了python环境。 3从平板导出 比较顺利 先关机。 wsl --shutdown 这里后两个我用不到&#xff0c;因为…

交叉销售与场景业务销售运营

交叉销售 交叉销售的定义 交叉销售是一种从横向角度开发产品市场的方式,是营销人员在完成本职工作以后,主动积极的向现有客户、市场等销售其他的、额外的产品或服务。 交叉销售的类型 补充销售 搭配销售个性化推荐奖励推荐 捆绑销售 交叉销售的意义 通过增加客户的转移成本…

Kafka-客户端使用

理解Kafka正确使用方式 Kafka提供了两套客户端API&#xff0c;HighLevel API和LowLevel API。 HighLevel API封装了kafka的运行细节&#xff0c;使用起来比较简单&#xff0c;是企业开发过程中最常用的客户端API。 LowLevel API则需要客户端自己管理Kafka的运行细节&#xf…

全栈开发中的安全注意事项:最佳实践和工具

安全性是当今数字环境中最重要的问题&#xff0c;而在全栈开发中这一点尤为重要。当企业努力创建强大且动态的应用程序时&#xff0c;他们必须应对复杂的安全威胁领域。在本文中&#xff0c;我们将探讨开发人员可以用来确保安全的全栈开发环境的最佳实践和工具。 1.1 全栈开发的…

YOLOv8原理深度解读,超级详细

整体架构 Backbone&#xff1a; Feature Extractor提取特征的网络&#xff0c;其作用就是提取图片中的信息&#xff0c;供后面的网络使用 Neck &#xff1a; 放在backbone和head之间的&#xff0c;是为了更好的利用backbone提取的特征,起着“特征融合”的作用。 Head&#xf…

金蝶云星空协同开发环境应用内执行SQL脚本

文章目录 金蝶云星空协同开发环境应用内执行SQL脚本 金蝶云星空协同开发环境应用内执行SQL脚本

电阻的运用

本文引注 https://baijiahao.baidu.com/s?id1749115196647029942&wfrspider&forpc 一、零欧电阻 在电子电路设计时经常用到的一种元件就是电阻&#xff0c;我们都知道电阻在电路中起到分压限流的作用。然而&#xff0c;实际使用时会用到一种特殊的电阻&#xff1a;零…

mysql数据恢复

使用MySQL第三方工具binlog2sql binlog2sql&#xff0c;一款基于python开发的开源工具&#xff0c;是由大众点评团队的DBA使用python开发出来的&#xff0c;从MySQL binlog解析出你要的SQL。根据不同选项&#xff0c;你可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。其功…

STM32CubeIDE串口空闲中断实现不定长数据接收

STM32F051空闲中断实现串口不定长数据接收 目的编程软件配置串口开中断中断程序 运行结果碰到的问题 目的 在串口输入不定长数据时&#xff0c;通过串口空闲中断来断帧接收数据。 编程软件 STM32CubeIDE STM32CubeMX配置MCU。通过对端口配置&#xff0c;自动生成程序&#x…