C++:初识函数模板和类模板
目录
一. 泛型编程
二. 函数模板
2.1 什么是函数模板
2.2 函数模板的实例化
2.2.1 函数模板的隐式实例化
2.2.1 函数模板的显示实例化
2.3 函数模板实例化的原理
2.4 模板函数调用实例化原则
三. 类模板
3.1 什么是类模板
3.2 类模板的实例化
一. 泛型编程
泛型编程,就是编写与类型无关的通用代码,使同一段代码可以适用于所有类型的数据。如:编写一个Swap函数,使其可以实现对所有内置类型数据的交换、编写一个链表类List,使其能够适用于存储所有数据类型的链表。
之前,如果我们想要编写支持所有数据类型的Swap函数,就需要编写多个重载函数,如:Swap(int& x, int& y)、Swap(double& x, double& y)。但是,函数重载会造成大量的代码冗余,而良好的代码对冗余是非常忌讳的。为了避免代码冗余,实现编写一份代码就适用于所有类型的数据,C++引入了模板的概念,而模板就是实现泛型编程的基础。
C++中的模板分为函数模板和类模板,由于C语言不支持模板,所有C语言也不支持泛型编程。
二. 函数模板
2.1 什么是函数模板
函数模板,本质上来说就是一个函数家族,在调用函数时,根据函数模板实例化出具体的函数,函数模板与参数类型无关。
定义函数模板的格式:
template <typename T1, typename T2, ... , typename T3>
函数返回值 函数名(参数列表) { }。
typename是函数模板关键字,可以使用class来替代,但不能使用struct来替代。
演示代码2.1以Swap函数为例,编写了一个Swap函数的函数模板,这个Swap函数可以对任何内置类型数据进行交换操作。
演示代码2.1:Swap函数模板
template<typename T>
void Swap(T& x, T& y)
{T temp = x;x = y;y = temp;
}
2.2 函数模板的实例化
根据实例化函数模板时是否指定参数类型,可分为隐式实例化和显示实例化。
2.2.1 函数模板的隐式实例化
隐式实例化,就是在调用函数时,不指定函数参数和返回值的类型,通过传入的数据,让编译器自己去推断类型。
演示代码2.2以Swap函数为例,分别向函数中传入了两个int型数据和两个double型数据进行交换,输出交换后的结果。根据输出结果可见,Swap函数模板成功对int型数据和double型数据进行了交换,证实了函数模板的通用性。
演示代码2.2:
int main()
{int a1 = 10, a2 = 20;double d1 = 10.11, d2 = 20.22;Swap(a1, a2);cout << "a1 = " << a1 << ", " << "a2 = " << a2 << endl;Swap(d1, d2);cout << "d1 = " << d1 << ", " << "d2 = " << d2 << endl;return 0;
}
2.2.1 函数模板的显示实例化
假设,我们传入一个int型参数和一个double型参数,试图实例化函数模板Swap:Swap(a1, d2)。当编译器看到a1时,会将T推断为int型数据,当编译器看到d2时,会将T推断为double型数据。但是,由于函数的模板参数列表中只有一个T,而一个T不能表示两种类型的数据,因此,这里会编译失败。
如果我们确实希望通过演示代码2.1中定义的Swap函数模板,实现int型数据和double型数据之间的数据交换,有以下两种方式可以实现:
- 强制类型转换:Swap(a1, (int)d1)
- 显示实例化:Swap<int>(a1, d1)
函数模板的显示实例化,就是通过在函数调用时,在函数名后面添加<模板参数类型>,显示地指定模板参数类型,从而省去了编译器自动推断模板参数类型的过程。
演示代码2.3定义了加法Add的函数模板,通过显示指定模板参数的类型为int和double进行调用,分别完成了整形数据和浮点型数据的加法操作。
演示代码2.3:
template<typename T>
T Add(T x, T y)
{return x + y;
}int main()
{int a = 10;double d = 20.2;cout << Add<int>(a, d) << endl;cout << Add<double>(a, d) << endl;return 0;
}
2.3 函数模板实例化的原理
函数模板其实并不是一个具体的函数,它相当于浇注制造中用到的模具,可用于生成具体的函数,但其本身不是函数。当要通过函数模板调用函数时,我们会传入模板参数,编译器则会根据模板参数类型,利用函数模板实例化出具体的函数。
如Swap函数,我们先后用它来交换char类型、int型和double型数据,编译器就会生成3个重载函数:void Swap(char& x, char& y)、void Swap(int& x, int& y)和void Swap(double& x, double& y),这三个函数存储在内存中不同的位置。
2.4 模板函数调用实例化原则
- 模板函数可以与非模板函数同名。
- 如果非模板函数能够很好地匹配调用参数的类型,那么编译器会优先调用非模板函数而不是根据函数模板实例化出函数来调用。
- 模板函数在传参时不允许存在隐式类型转换,但非模板函数允许隐式类型转换。
三. 类模板
3.1 什么是类模板
类模板与函数模板类似,通过模板参数列表,来使类中的成员函数参数和成员变量可以为任何想要的数据类型。
类模板的定义格式:
template<typename T1, typename T2, ... , typename n)
class 类名
{
成员函数列表 ......
成员变量列表 ......
}
演示代码3.1以栈类为例,定义了一个可以实例化为存储任何数据类型的栈。其中包括4个显示定义的成员函数:构造、析构、压栈和打印,包括三个成员变量:指向存储数据内存区域的指针_a、栈顶下标_top、栈容量_capacity。
该栈模板类引入T作为模板参数,其中压栈函数的参数和成员变量_a均涉及参数T,在实例化时,T可以被解析为多种类型(如int、double、char等)。
抛开类模板的实际功能来讲,T还可以实例化为自定义类型,如果T被实例化为自定义类型,那么这创建模板类对象时,会去调用T的构造函数。
演示代码3.1:
template <class T>
class Stack //栈类
{
public:Stack(int capacity = 10);~Stack();void Push(T x);void Print();private:T* _a;int _top;int _capacity;
};//类模板成员函数定义和声明分离
//函数返回值 类名<模板>::函数名(参数列表)
template <class T>
Stack<T>::Stack(int capacity): _capacity(capacity), _top(0)
{_a = new T[capacity];
}template <class T>
Stack<T>::~Stack()
{delete[] _a;_top = _capacity = 0;
}template <class T>
void Stack<T>::Push(T x)
{_a[_top++] = x;
}template <class T>
void Stack<T>::Print()
{int i = 0;for (i = 0; i < _top; ++i){std::cout << _a[i] << " ";}std::cout << std::endl;
}
3.2 类模板的实例化
与函数模板既可以显示实例化也可以隐式实例化不同,类模板只能显示实例化。即:告知编译器模板参数的类型。
类模板实例化格式:类名<模板参数类型> 对象名
演示代码3.2展示了对于栈类模板的实例化,分别实例化处一个int栈对象st1和double栈对象st2,对两个栈进行压栈操作并打印栈中数据,证实了该栈类模板能够适用于各种数据类型的栈。
演示代码3.2:
int main()
{//函数模板可以显示调用也可以隐式调用//但类模板只能显示调用Stack<int> st1;st1.Push(1);st1.Push(2);st1.Push(3);st1.Print();Stack<double> st2;st2.Push(1.1);st2.Push(2.2);st2.Push(3.3);st2.Print();return 0;
}
相关文章:
C++:初识函数模板和类模板
目录 一. 泛型编程 二. 函数模板 2.1 什么是函数模板 2.2 函数模板的实例化 2.2.1 函数模板的隐式实例化 2.2.1 函数模板的显示实例化 2.3 函数模板实例化的原理 2.4 模板函数调用实例化原则 三. 类模板 3.1 什么是类模板 3.2 类模板的实例化 一. 泛型编程 泛型编程…...
3.8妇女节如何做好TikTok网红营销?
3月8日是国际妇女节,这一节日已经成为全球关注女性权益和平等的标志性日子,TikTok上话题#internationalwomensday累计播放超10亿次,话题#WomensDay2023累计播放量也将近300万次。 这个特别的日子为品牌提供了一个很好的营销机会。据Nox聚星了…...
使用Advanced Installer打包程序及运行环境
Advanced Installer 工具版本:20.1.1 设置产品信息 选中右侧【Product Details】输入产品信息 设置文件和文件夹 添加使用VS发布之后的程序文件夹 设置文件夹刷新 选中文件夹,右键选择属性,选中Synchronize标签。启用“Synchronize conten…...
华为OD机试真题Python实现【计算堆栈中的剩余数字】真题+解题思路+代码(20222023)
计算堆栈中的剩余数字 题目 向一个空栈中依次存入正整数 假设入栈元素N(1<=N<=2^31-1) 按顺序依次为Nx … N4、N3、N2、N1, 当元素入栈时,如果N1=N2+...Ny(y的范围[2,x],1 <= x <= 1000) 则 N1 到 Ny 全部元素出栈,重新入栈新元素M(M=2*N1) 如依次向栈存储6、1、…...
企业文件数据泄露防护(DLP)
什么是数据丢失防护 数据丢失防护 (DLP) 是保护数据不落入坏人之手的做法。如今,数据传输的主要问题是使大量数据容易受到未经授权的传输。通过设置足够的安全边界,您可以控制数据在网络中的移动。由于您的数据非常有价值&#x…...
不考虑分配与合并情况下,GO实现GCMarkSweep(标记清楚算法)
观前提醒 熟悉涉及到GC的最基本概念到底什么意思(《垃圾回收的算法与实现》)我用go实现(因为其他的都忘了,(╬◣д◢)ムキー!!) 源码地址(你的点赞,是我开源的…...
利用HGT聚类单细胞多组学数据并推理生物网络
单细胞多组学数据允许同时对多种组学数据进行定量分析,以捕捉复杂的分子机制和细胞异质性。然而现有的工具不能有效地推断不同细胞类型的活性生物网络以及这些网络对外部刺激的反应。 来自:Single-cell biological network inference using a heterogen…...
杂记——18.VSCode的下载及使用
这篇文章,我们来讲一下VSCode,讲一下如何下载及使用VSCode 目录 1.VSCode的下载 1.1VSCode的简介 1.2VSCode的下载与安装 1.2.1下载 1.2.2安装 2.VSCode的使用 2.1界面 2.2基础设置 2.3禁用自动更新 2.3自动保存设置 2.4Vscode更换主题 2.5…...
【独家】华为OD机试 - 最少停车数(C 语言解题)
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明本期…...
顶级动漫IP加持之下,3A策略游戏Mechaverse如何改变GameFi
2021年是元宇宙发展的元年,元宇宙与GameFi创造了一波又一波市场热点。在经历第一波热潮之后,元宇宙的到来让不少人看到了加密市场的潜力,同时大家也意识到这将是未来的重要方向。如何将元宇宙推向更广阔的市场,让更多人能够轻松进…...
一款丧心病狂的API测试工具:Apifox!
你好,我是测试开发工程师——凡哥。欢迎和我交流测试领域相关问题(测试入门、技术、python交流都可以) 我们平时在做接口测试的时候,对于一些常用的接口测试工具的使用应该都非常熟悉了: 接口文档:Swagge…...
【前端学习】D2-2:CSS基础
文章目录前言系列文章目录1 Emmet语法1.1 快速生成HTML语法结构1.2 快速生成CSS样式语法1.3 快速格式化代码2 CSS复合选择器2.1 什么是复合选择器2.2 后代选择器(*)2.3 子选择器2.4 并集选择器(*)2.5 伪类选择器2.6 链接伪类选择器…...
Flink / Scala 实战 - 19.ProcessFunction 删除 key 的上一个定时器 TimeTimer
一.引言 ProcessFunction 原始执行状态为每个 key 注册一个较长时间 TimeTimer 并在这期间将所有对应 key 的数据都收集起来,到期完成触发。现在接到新的需求,要求判断数据类型,当特殊标识的数据到达后,需要将 TimeTimer 到期的时间提前。因此需要删掉当前 key 之前注册的老…...
MSTP基础
MSTP基础引入背景技术概览PVSTP(过渡)MSTP单生成树的缺陷1:部分VLAN不通单生成树的缺陷2:无法实现流量的负载分担多生成树解决单生成树实例引入背景 RSTP在STP基础上进行了改进,实现了网络拓扑快速收敛。但由于局域网…...
当ChatGPT遇见stable-diffusion,你不敢相信的创意艺术之旅!
前言 欢迎来到一场创意的旅程,这里将聚焦于 ChatGPT 和 stable-diffusion 这两个令人激动的技术。在这篇文章中,我们将会探索这两种技术如何结合使用,为艺术创作带来全新的可能性。我们将探讨如何利用 ChatGPT 生成富有想象力的创意…...
一文搞定!postman接口自动化测试【附项目实战详解】
目录:导读 | 接口结果判断 功能区 脚本相关 代码模板 | 集合(批量)测试 变化的参数数据 定期任务 接口执行顺序 数据传递 | 解决依赖问题 假设场景 Postman 中的操作 运行 写在最后 附带项目实战教程地址:postman接口自动化测试使用教程项…...
ctfshow【菜狗杯】wp
文章目录webweb签到web2 c0me_t0_s1gn我的眼里只有$抽老婆一言既出驷马难追TapTapTapWebshell化零为整无一幸免无一幸免_FIXED传说之下(雾)算力超群算力升级easyPytHon_P遍地飘零茶歇区小舔田?LSB探姬Is_Not_Obfuscateweb web签到 <?ph…...
旋转数组的几种做法
千淘万浪虽辛苦,吹尽黄沙始到金。 ——刘禹锡 第一种方法:遍历整个数组 题目描述: 一个数组A中存有N (N>0) 个整数,允许使用另外数组,将每个整数循环向右移动M(M>0)个位置。如果需要…...
创建虚拟机、添加镜像以及配置虚拟机
一、创建虚拟机 1、点击 “创建新的虚拟机” 2.选择“自定义配置” 到后面可以选择硬件的类型 3.默认值就行 4.选择 “稍后安装操作系统” 5.操作系统选择 “Linux”,版本结合镜像自行选择 6. 虚拟机的名称自行定义, 就是上述显示出来的名称。 虚拟机…...
Godot Engine 4.0横空出世,Vulkan大怪兽加持,画质提升简直亮瞎眼
【CSDN 编者按】经历了漫长的等待,万众瞩目的 Godot Engine 4.0 正式版在其 3.0 版本发布 5 年以后,终于带着海量令人兴奋的新功能横空出世! 整理 | 开发游戏的老王 责编 | 王子彧 出品 | CSDN(ID:CSDNnews)…...
CorelDRAWX4的VBA插件开发(四十五)建立类(2)汇总相似功能简化重复代码:一键建立设计外框加出血线和等分折页线
在上一节中已经建立好了类,那么这一节我们来调用它,先建立一个面板 然后修改框体名称 然后从左侧新建一些按钮并且以拼音为结尾进行命名 Private Sub CheckBox2_zheYe_Click() 鼠标按下几折页单选时触发If Me.CheckBox2_zheYe ThenMe.TextBox3_zheYeShu.Enabled True 让右…...
我的十年编程路 2017年篇
2016和2017,这两年是我飞速发展的两年。一方面是技术、工作能力,另一方面是对人生的思考。 随着技术能力的不断提升,博客也随之更新。在2017年伊始,我收到了CSDN学院的讲师邀请函。没错,那个时候我就有机会做视频课了…...
hadoop有多个输入路径怎么处理
在Hadoop中,可以使用FileInputFormat的addInputPath方法来添加多个输入路径。以下是实现步骤:创建一个Job对象,并设置相关的参数和配置信息。调用FileInputFormat的addInputPath方法添加输入路径。例如:FileInputFormat.addInputP…...
day6 ServletContext
ServletContext 一个Servlet对象对应一个ServletConfig。100个Servlet对象则对应100个ServletConfig对象。 只要在同一个webapp当中,只要在同一个应用当中,所有的Servlet对象都是共享同一个ServletContext对象的。 ServletContext对象在服务器启动阶段…...
Dockerfile部署SpringBoot项目
Dockerfile部署SpringBoot项目 文章目录 利用Dockerfile部署SpringBoot项目 1、创建一个SpringBooot项目并且打成jar包2、在Linux中创建一个文件夹,来做docker测试3、将jar包上传到Linux中4、编写Dockerfile文件5、制作镜像6、启动容器7、查看容器启动日志8、访问接…...
Java面向对象特征之三:多态
一:面向对象三大特征之三:多态 1.多态是什么? 同类型的对象,执行同一个行为,会表现出不同的行为特征。 比如:猫和狗都是动物类型,执行同一个行为,但是会表现出不同的行为特征&…...
基于ATX自动化测试解决方案
在整车开发中,诊断功能实现后需要进行测试验证。测试验证主要分为两个方面:诊断协议层测试和诊断功能测试。诊断协议层测试:需要对服务层服务定义、传输层相关时间参数进行测试验证;诊断功能测试:需要对各诊断功能项&a…...
Qt学习5-Qt Creator文件操作(哔站视频学习记录)
实现文件编辑器代码 目录 一、代码要点 二、重点函数 1、conncet 2、getOpenFileName 3、getSaveFileName 4、读取文件到textEdit 5、textEdit保存到文件 三、全部代码 mainwindow.h mainwindow.cpp 一、代码要点 MainWindow的菜单栏实现;connect函数连接…...
LeetCode15三数之和 容易理解版本
题目: 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三…...
Spring Boot 3.0系列【11】核心特性篇之国际化
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot版本3.0.3 源码地址:https://gitee.com/pearl-organization/study-spring-boot3 文章目录 前言基础知识国际化简介浏览器语言LocaleMessageSourceMessageSourcePropertiesLocaleResolver案例演示案例一:后台消息国…...
英文网站做百度权重有意义吗/百度关键词seo优化
第一部分 调研评测 Windows版BUG 1.OCR强力取词功能:对于图片中的印刷体文字识别率较高,但对于手写文字识别率低,特别是识别生活中的图片,比较明显,经常识别出乱码。且该功能开启后,CPU的负担有明显加重。…...
网站建设个人总结/在百度平台如何做营销
小编觉得吧证件照这种东西就有一种“让人露出真面目”的魔力身份证照片更是证件照里的重灾区超过八成的网友表示身份证照是世界上最丑的照片它掀起你的减龄刘海将卡姿兰大眼睛照成死鱼眼让你的脸看起来像被车碾过一样又平又宽很多人对身份证照深恶痛绝绞尽脑汁想换照片某市民谎…...
企业可以做哪些网站有哪些/郑州网络营销推广公司
小编精心收集:为金三银四准备,以下面试题先过一遍,为即将到了的面试做好准备,也过一遍基础知识点。一、RabbitMQ1.rabbitmq 的使用场景有哪些?2.rabbitmq 有哪些重要的角色?3.rabbitmq 有哪些重要的组件&am…...
网站建设需要资料/营销方案案例范文
MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2、MD3和MD4发展而来。 MD5将任意长度的“字节串”变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法࿰…...
帮别人做彩票网站/口碑seo推广公司
linux下给目录下所有子目录和文件赋权 chmod -R 777 * 给所有文件指定用户和用户组 chown - R wang.users /his 把目录/his及其下的所有文件和子目录的属主改成wang,属组改成users。...
做网站主要学什么条件/测试自己适不适合做销售
本文讲的是域渗透提权分析工具 BloodHound 1.3 中的ACL攻击路径介绍,简介和背景2014年,Emmanuel Gras和Lucas Bouillot在“ 信息通信技术研讨会”(Symposium on Information and Communications)上发表了题为“ Chemins decontrle…...