C++之模板

news2024/12/26 21:56:38

目录

泛型编程

模板

函数模板

函数模板的实例化

隐式实例化 

显示实例化

类模板


我们知道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的基础,小伙伴们一定要掌握模板的相关内容。

本期内容到此结束^_^

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c/c++ 结构体、联合体、枚举

结构体 结构体内存对齐规则&#xff1a; 1、结构体的第一个成员对齐到结构体变量起始位置偏移量为0的地址处 2、其他成员变量要对齐到某个数字&#xff08;对齐数&#xff09;的整数倍的地址处。 对齐数&#xff1a;编译器默认的一个对齐数与该成员变量大小的较小值。 vs 中…

Golang学习之路一开山篇

Golang学习之路一开山篇 初识 Golang 我第一次接触 Golang 是在2016年, 当时在深圳工作, 项目需要用Golang, 当时在犹豫要不要学还是走, 毕竟Java开发搞了很多年了, 说放弃还是有难度的, 其实也不是放弃Java, 说不定其他项目还是要使用Java. 在领导的再三劝说下, 开启了Golan…

mysql原理--B+树索引

1.没有索引的查找 1.1.在一个页中的查找 (1). 以主键为搜索条件 可以在 页目录 中使用二分法快速定位到对应的槽&#xff0c;然后再遍历该槽对应分组中的记录即可快速找到指定的记录。 (2). 以其他列作为搜索条件 这种情况下只能从 最小记录 开始依次遍历单链表中的每条记录&am…

排序 | 冒泡插入希尔选择堆快排归并计数排序

排序 | 冒泡插入希尔选择堆快排归并计数排序 文章目录 排序 | 冒泡插入希尔选择堆快排归并计数排序冒泡排序插入排序希尔排序选择排序堆排序快速排序--交换排序三数取中快速排序hoare版本快速排序挖坑法快速排序前后指针法 快速排序--非递归实现归并排序归并排序非递归实现非比…

「Swift」Xcode多Target创建

前言&#xff1a;我们日常开发中会使用多个环境&#xff0c;如Dev、UAT&#xff0c;每个环境对应的业务功能都不同&#xff0c;但每个环境之间都只存在较小的差异&#xff0c;所以此时可以使用创建多个Target来实现&#xff0c;每个Target对应这个一个App&#xff0c;可以实现一…

mac视频调色 DaVinci Resolve Studio 18 中文 for Mac

DaVinci Resolve Studio 18是一款功能强大、专业可靠的视频编辑软件&#xff0c;适用于各种规模的媒体项目制作。无论是独立制片人还是大型制片公司&#xff0c;都可以借助该软件进行高质量的视频创作和后期制作。 得编辑工作更加高效和灵活。 调色和色彩校正&#xff1a;软件…

【亚马逊云科技】使用Vscode Amazon-Q完成GUI界面粉笔脚本开发

本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 前言 亚马逊云科技-Q&#xff0c;可以快速获得紧迫问题的相关答案&#xff0c;解决问题…

Java研学-MyBatis框架

一 MyBatis框架 1 框架介绍 框架&#xff1a;对基础代码进行封装并提供相应的API&#xff0c;调用API可省去一些代码的编写&#xff0c;从而提高效率。一个好的框架一定是经过测试&#xff0c;自身的功能已经实现&#xff0c;可以完成特定的功能。 2 MyBatis 框架 MyBatis 框…

十四 动手学深度学习v2计算机视觉 ——转置矩阵

文章目录 基本操作填充、步幅和多通道再谈转置卷积不填充&#xff0c;步幅为1填充为p&#xff0c;步幅为1填充为p&#xff0c;步幅为s 基本操作 填充、步幅和多通道 填充&#xff1a; 与常规卷积不同&#xff0c;在转置卷积中&#xff0c;填充被应用于的输出&#xff08;常规卷…

ShellCode注入程序

程序功能是利用NtQueueApcThreadEx注入ShellCode到一个进程中&#xff0c;程序运行后会让你选择模式&#xff0c;按1为普通模式&#xff0c;所需的常规API接口都是使用Windows原本正常的API&#xff1b;在有游戏保护的进程中Windows原本正常的API无法使用&#xff0c;这时候需要…

在windows系统搭建LVGL模拟器(codeblock工程)

1.codeblock准备 下载codeblock(mingw)&#xff0c;安装。可参考网上教程。 2.pc_simulator_win_codeblocks 工程获取 仓库地址&#xff1a;lvgl/lv_port_win_codeblocks: Windows PC simulator project for LVGL embedded GUI Library (github.com) 拉取代码到本地硬盘&…

Fabric使用自己的链码进行测试-go语言

书接前文 Fabric链码部署-go语言 通过上面这篇文章&#xff0c;你可以部署好自己的链码 &#xff08;后面很多命令是否需要修改&#xff0c;都是根据上面这篇文章来的&#xff0c;如果零基础的话建议先看上面这篇&#xff09; 就进行下一步 在测试网络上运行自己的链码 目…

STM32单片机项目实例:基于TouchGFX的智能手表设计(5)硬件驱动层程序设计

STM32单片机项目实例&#xff1a;基于TouchGFX的智能手表设计&#xff08;5&#xff09;硬件驱动层程序设计 目录 一、 概述 二、 新建工程与外设配置 三、 TouchGFX配置 四、 增加TouchGFX关键驱动 一、 概述 本文内容主要进行工程新建&#xff0c;硬件外设的配置以及添加…

《PySpark大数据分析实战》-10.独立集群模式的代码运行

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

03. 医院设置_后端

1、Swagger2 测试工具 编写和维护接口文档是每个程序员的职责&#xff0c;根据Swagger2可以快速帮助我们编写最新的API接口文档&#xff0c;再也不用担心开会前仍忙于整理各种资料了&#xff0c;间接提升了团队开发的沟通效率。 swagger通过注解表明该接口会生成文档&#xf…

CSC公派研究生项目|电气工程在读博士谈丹麦奥尔堡大学联培体会

2023年已近兔尾&#xff0c;很多人已经开始新一年的规划&#xff0c;对于国内在读博士而言&#xff0c;申请国家留学基金委&#xff08;CSC&#xff09;公派研究生项目也开始列入议事日程&#xff0c;然而&#xff0c;如何申请&#xff1f;在国外学习收获如何&#xff1f;本篇知…

IDEA小技巧

目录 1. IDEA自动添加注释 创建类的时候自动添加注释 创建函数、方法的注释 1. IDEA自动添加注释 参考文档&#xff1a;idea java 自动添加文件注释 idea新建类自动注释_mob6454cc73c728的技术博客_51CTO博客 【操作工具】IDEA创建类及已有类添加注释-详细操作_idea设置创建…

【状态机FSM 序列检测 饮料机_2023.12.1】

同步状态机 概念 同步状态机&#xff08;同一脉冲边沿触发&#xff09;&#xff1a;有限个离散状态及某状之间的转移 异步状态机无法综合 分类 Moore状态机 只和状态有关&#xff0c;与输入无关 Mealy状态机 和状态和输入都有关 Mealy型比Moore型少一个状态 结构 由状态寄…

AI日报:OpenAI向新用户重新开放ChatGPT Plus订阅

欢迎订阅专栏 《AI日报》 获取人工智能邻域最新资讯 文章目录 总览Chatgptplus重新开放订阅#暂停原因功能 OpenAI的1000万美元安全人工智能拨款拨款初衷学术捐赠 总览 ChatGPT Plus再次向新用户开放&#xff0c;但目前每三小时限制发送40条消息。 OpenAI还宣布拨款1000万美元…

喜报!Coremail荣获2023信创“大比武”优秀生态融合奖

近期&#xff0c;2023信创“大比武”金融业务创新应用赛道&#xff08;简称金融赛道&#xff09;活动正式落下帷幕。经过赛程的层层考核&#xff0c;中泰证券股份有限公司&#xff08;简称“中泰证券”&#xff09;与Coremail联合组成的“中泰证券CACTER邮件安全保卫队”最终在…