c++----初识模板

news2024/12/27 13:46:32

        大家好,这篇博客想与大家分享一些我们c++中比较好用的知识点。模板。首先咧,我们都知道模板嘛,就是以前人的经验总结出来的知识。方便我们使用。这里的模板也是一样的。当我们学习过后,对于一些在c中的自定义函数,我们在c++中使用就会很方便了。但是因为我们这里只是初识。因为我们现在学识尚浅,太过高深的话,就一点过载了,所以我们这里就暂时交给大家如何辨认和使用简单的模板。

泛型模板

        首先我们可以从我们的标题看到我们这一小节讲的是广泛的模板,就是使用的范围相对较广,但是只是较广并不是通用。我们这里就以我们以前在c中常使用的一个自定义函数swap来说,但其实我们在c中就说过,我们学习了c++就不需要再自己写了,也不需要写头文件,因为我们c++中swap很有可能会被间接包含所以我们通常是直接使用,这里我们为了方便教学就以这个为例。

      大家都知道,我们平常的swap是确定了参数类型的,不能不同参数进行交换,就像我们下面的图片:

        在我们c的时候为了应对不同的参数类型所以我们需要写多个参数版本。使用函数重载虽然可以实现,但是有一下几个不好的地方:

1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数

2. 代码的可维护性比较低,一个出错可能所有的重载均出错
那能否 告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码 呢?
         如果在 C++ 中,也能够存在这样一个 模具 ,通过给这个模具中 填充不同材料 ( 类型 ) ,来 获得不同 材料的铸件 ( 即生成具体类型的代码) ,那将会节省许多头发。巧的是前人早已将树栽好,我们只 需在此乘凉。 泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。

函数模板

        对于我们的函数模板,它代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。已就是说。我们的c++模板不会受到参数类型的限制,只要我们写的参数个数正确就可以了。虽然我这里很简单说,只需要确定参数个数就可以了。但其实也真的很简单。

        那么我们就来看看函数的模板是如何书写的。首先我们要先写一个:template<typename T1, typename T2,......,typename Tn> 。大体是这样的但是个数就是自己确定。是不是很简单啊。那么我们来写一个swap模板,并且看看如何使用的:         上面的图片,大家可以看到在使用模板前,我们先写了一个声明。然后写的我们模板。这里大家是否有留意到我们声明的时候只写了一个参数类型啊,就是我们这里template<typename T>中只有一个参数。这就表明了我们这里的模板参数类型只能有一种参数类型。

        我想大家看了上面的那句话应该会想到一个疑问吧,这就是啥意思啊。上面写了一个参数,就代表只有一种参数类型了。那是不是我上面多写几个,那么我就可以在模板中使用多种参数类型了呀。但确实是这样的,我们可以在声明的时候多些几种,那么模板就可以多使用几种,那我们来看看例子:

       这里我们是没有报错的,这是因为我们在上面写了两个声明的类型,所以我们在模板中可以使用两种参数变量,虽然结果可能不尽人意但是我们的却还是确定了一点。我们如果在前面写多个参数那么下面的模板就可以使用多种参数类型。

:括号里面的声明是只能写typename还可以写成clsaa,但是大家不要多想以为class可以写,那么struct也可以写。这就错了。表明参数类型能个数的就只有这两种表达。没有其他的了

函数模板的原理,对于我们学习的人来说,主打一个刨根问底。那么我们对于这个函数模板多多少少也是需要了解的。但其实大家如果看到这里了,就应该对函数模板的原理也差不多了吧。毕竟我们的标题就写的很清楚了啊。模板嘛。函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器我感觉有点像一个没有灵魂的人,只要有灵魂进入这幅躯体,那么这幅躯体就可以凭借这个灵魂带来的思想来完成自己的心愿。就像可以被人随意控制的木偶一样。大家可以看一下下面的图片:       这里就有点像我上面写的那个灵魂一样。只要想用就进入这幅空壳,凭借这幅躯体就可以做出其他的事情。但如果稍微官方一点的话就是:在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。这个大家可以复杂理解,也可以简单思考,反正我觉得稍微知道是个啥意思就可以了,如果深入太多的话,就可能有点吃不消了。

函数模板的实例化:大家可能看到这个小标题会有点懵。啊。实例化,什么个意思怎么会用在这里啊。大家别急。用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化这里我们知道了示例化有两种。一个是显示一个是隐式。那么我们就来先看看显示实例化:

       我们这里的Add只写了一种参数个数,如果按我们前面说的话,不是只能有一种参数类型吗?这里怎么有两种啊。但大家应该也看到了,在我们调用的前面写了一个<int>。这就好比我们在c中写过的强制类型转换。只是我们写的这里是将这两个全都转换成int,int转换为int不变嘛,但是我double可以转换为it强制类型转换,当然也可以这样写:

      反正如果我们写的参数个数类型只写了一个的话,我们可以将我们不同的参数类型进行转换,然后使用。还有对于隐式实例化的话就是比较简单的,其实就是我们普通的使用方法也是使用转换,就是我们相同的参数类型:

       这就是我们说的隐式类实例化,就是我们平常的使用方法,但是对于我们如果想用两种不同的参数类型,并且我们的参数类型个数只有一个的话,就只能强转或者我们刚刚的显示实例化。 

模板参数的匹配原则 :不知道大家是否会有一个想法,就是因为我们c++可以重载函数,如果我们创建一个模板,然后再创建一个重载函数,并且它们的参数是一样的,名字是一样的。那如果我调用的话会调用哪一个呢?对于这个大家其实可以有一个很简单的想法。例如编译器是一个人的话,我其实个人觉得人都是想着少做一点是一点。反正钱拿的是一样的。那为什么我不躺平一点呢?以现在的情况为例,如果有一个自定义函数的参数类型与模板函数是一样的,那么如果调用的话肯定是直接调用使用人写的那个,因为如果使用模板函数的话,编译器还会自己动一下,我干嘛还要自己动呢?你反正你已经写了,是吧?

       这里我是简单的用f11调试给大家看的,虽然可能大家会怀疑,但确实是这样,如果当一个非模板函数与模板函数同时调用的话,会先调用非模板函数,大家知道就可以了。模板函数不允许自动类型转换,但普通函数可以进行自动类型转换。

类模板

       大家也看到了上面我们所有的文章都是依照函数来写的,但是我们c++呢肯定不只有函数,我们前面学的最多的就是类了,我们那也是有模板的。其实对于类的模板格式与我们的函数模板格式相差无几。区别就是我们类的写法,我们自定义函数的写法是不一样的。那么我们看一下类模板的定义格式是什么样的?

类模板的定义格式:

template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};

        我们前面说过类模板的第一个是与我们的函数模板格式差不多,只是融汇了自己各自的特点。也许大家会想类模板有什么作用呢?

  1. 一些类主要用于存储和组织数据元素
  2. 类中数据组织的方式和数据元素的具体类型无关
  3. 如:数组类,链表类,Stack类,Queue类,等

C++中将模板的思想应用于类,使得类的实现不关注数据元素的具体类型,而只关注类所需要实现的功能。

实现类模板:

  1. 以相同的方式处理不同的类型
  2. 在类声明前使用template进行标识
  3. < typename T >用于说明类中使用的泛指类型T 

       这里我们是以我们C中使用过的扩容。大家可能很难看出来,但其实我们不看这个,我们主要是看我们的模板是如何使用的。后面大家加油以此为蓝本来写,也许大家会问啊,关于模板函数我们知道的少怎么分析这个类模板函数列:

1. 与函数模板不同,只能显示指定具体类型,无法自动推导。
2. 声明的泛指类型T 可以出现在类模板的任意地方
3. 编译器对类模板的处理方式和函数模板相同
a) 从类模板通过具体类型产生不同的类
b) 在声明的地方对类模板代码本身进行编译
c) 在使用的地方对参数替换后的代码进行编译

        大家可以多理解上面分析。并且大家需要知道的一个不能忘的点就是我们类模板的头文件与源文件不能分开。具体是什么原因。在下暂时还不知道。但是我尝试过分开确实会报错的,所以大家现在知道不能分开就可以了。

类模板的实例化: 类模板实例化与函数模板实例化不同, 类模板实例化需要在类模板名字后跟 <> ,然后将实例化的 类型放在 <> 中即可,类模板名字不是真正的类,而实例化的结果才是真正的类
// Stack是类名,Stack<int>才是类型
Stack<int> st1; // int
Stack<double> st2; // double

总结

       好的,上面这些就是本篇博客想与大家分享的模板的一些相关的基础知识,我知道可能大家会很多的不了解,尤其是类模板的。相较于函数模板的话,类模板确实要有更多的知识点,但是大家不要害怕,我们可以多稍微多理解几遍,看几遍就可以了解的更多了。模板嘛,毕竟是我们c++中最好用的一个东西啊,因为相较于c中它没有我们c++有就更好用了。好,鄙人在这里祝各位前程似锦!!!

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

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

相关文章

QList 的访问方式list.at(index) 和 list[index] 对比

QList 是 Qt 框架中提供的一个模板容器类&#xff0c;用于存储和操作一系列元素。它提供了两种不同的方式来访问容器中的元素&#xff1a;.at()成员函数和下标运算符 []。以下是这两种方式的区别&#xff1a; 1. QList::at() 方法 at()是一个成员函数&#xff0c;它允许通过索…

04--Docker

前言&#xff1a;前面写过关于DockerKubernetes的部署&#xff0c;主要是针对国产化linux系统的适配问题&#xff0c;并没有对docker进行复习。这里整理一下docker的知识点&#xff0c;用作容器化微服务的起点&#xff0c;主要为日常工作配置使用&#xff0c;本章可能有点长&am…

详解Xilinx FPGA高速串行收发器GTX/GTP(4)--TX/RX接口的数据位宽和时钟设计

目录 1、时钟设计 2、TX接口 3、接口位宽与时钟的关系 4、时钟来源方案 5、TX端内部的时钟分频设计 6、RX接口 文章总目录点这里:《FPGA接口与协议》专栏的说明与导航 1、时钟设计 GT收发器内部比较复杂,所使用的时钟就不止一个,比较主要的时钟有两个,架构…

做好网络安全风险管理必备的5种能力

网络安全风险管理和网络安全防护是两个密切相关但不可互换的概念&#xff0c;网络安全防护侧重于应对攻击和响应正在发生的安全事件&#xff0c;而网络安全风险管理则强调从更全面的视角去评估企业的安全状况和面临的威胁态势&#xff0c;包括了从对组织运营、商誉、财务和合规…

值得注意!家里有带毛发动物就有浮毛?宠物空气净化器一键净化

上次跟朋友逛完街去她家&#xff0c;她家热情的哈基米开门就一个猛冲&#xff0c;我朋友接住就是一顿猛亲&#xff0c;亲猫一时爽&#xff0c;汗液粘着猫毛&#xff0c;粘得满手臂、满脸都是&#xff0c;看得鼻炎星人头皮发麻...好多养宠物的都说&#xff0c;梳毛根本不管用&am…

关于let 、const和Object.freeze的使用记录

let和const的使用差异 let对象变量&#xff0c;可以修改对象属性&#xff0c;可以给变量重新赋值 const对象变量&#xff0c;可以修改对象属性&#xff0c;不可以给变量重新赋值 Object.freeze()返回一个不可变对象&#xff0c;需要接收返回值。不会改变原参数的性质

LVS详解及其NAT模式与DR模式部署(全网最详细!!!)

文章目录 LVS集群概念集群和分布式 LVS运行原理LVS简介LVS专业术语工作原理LVS调度算法ipvsadm常用命令 LVS工作模式及其原理NAT模式DR模式TUN模式fullnet模式 部署NAT模式集群案例DR模式&#xff08;企业中最常用&#xff09;LVS持久链接&#xff08;session回话问题解决&…

SimpleITK C++版在windows 下编译

一般都是用python 版的SimpleITK&#xff0c;因为项目需要集成到C Qt上&#xff0c;然后ITK用起来又不如SimpleITK方便&#xff0c;所有就编译了C版的Sitk,下面记录下过程。 版本对应 SimpleITK 编译需要ITK ,而且不同版本需要对应不同的ITK&#xff0c;sitk 2.2.1 对应ITK 5…

基于Hadoop的海量电商用户行为分析及机器学习购买预测研究【购物行为分析、100万条数据案例项目】

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主引言研究背景国内外研究现状研究目的研究意义 关键技术理论介绍Hadoop集群搭建及数据准备Hadoop全套组件搭建数据集介绍数据预处理 基于大数据的电商用户行为指标分析HIve准备数据表flume配…

在哪些行业中,3D 技术发挥了重要作用?

3D技术目前常见于行业或领域中的应用&#xff0c;主要包括3D数字孪生、3D打印等。3D数字孪生技术作为一种前沿技术&#xff0c;在多个行业中发挥着重要作用&#xff0c;它通过创建物理实体的数字化副本&#xff0c;实现对实体的实时监控、预测和优化。以下是一些3D数字孪生技术…

【总结】TCP/IP四层模型的理解

在开始之前放上一张本文章的核心图片&#xff0c;要一直记住图中的内容&#xff01;&#xff01;&#xff01; 一、概念理解 首先我们知道分析网络的时候有两种模型&#xff0c;一种是OSI七层模型&#xff0c;另一种就是TCP/IP四层模型。一般来说&#xff0c;我们常用的就是TC…

医疗工厂网络同步时钟,子母钟系统结构,可使用十年以上

在医疗和工业领域&#xff0c;准确的时间信息对于确保各项工作的高效运行至关重要。网络同步时钟系统因其高精度、易维护等特点&#xff0c;成为现代医疗工厂不可或缺的时间管理工具。本文将详细介绍网络同步时钟系统的优点及其技术细节。 一、网络同步时钟优点 网络同步时钟系…

工业设计用什么CAD软件?SolidWorks 成为您创意实现的得力助手

随着科技的发展&#xff0c;工业设计已经进入了数字化时代。对于设计师来说&#xff0c;选择一款高效、功能全面的设计软件至关重要。在市场上众多的CAD&#xff08;计算机辅助设计&#xff09;软件中&#xff0c;SolidWorks因其出色的性能和广泛的适用性而备受青睐。本文将介绍…

各地区搭子群扩列群h5公众号小程序app开源版开发

各地区搭子群扩列群多开h5公众号小程序app开源版开发 多端应用&#xff0c;源码开源支持自主二开&#xff1b;域名授权。 搭子群和扩列群通常是用来帮助人们找到志同道合的朋友或活动伙伴的社交平台。这些平台可以采用H5页面、微信公众号、小程序或独立的应用程序等形式。下面…

winform 设置TabControl中tab标签的宽度

问题&#xff1a; tabpage标签太挤了&#xff0c;标签间的间隔也不明显。解决方法&#xff1a; 将TabControl的SizeMode属性设为Fixed设置ItemSize的大小(width) 调整后效果&#xff1a;

暗区突围端游下载不了/下载失败/下载太慢的有效解决办法分享

暗区突围端游的第一次测试已经过去了一段时间了&#xff0c;毕竟是第一次测试&#xff0c;当时还是有很多问题的&#xff0c;比如说很多玩家根本拿不到测试资格&#xff0c;还有些是因为游戏优化太差&#xff0c;卡的就玩不了。现在这些问题通通不用担心了&#xff0c;端游在13…

和鲸科技助力 Datathon 会前培训成功举行,“理-工-医-信”跨学科合作,以数据驱动医疗实践

2024 年 8 月 3 日&#xff0c;由解放军总医院和中国生物医学工程学会临床医学工程分会共同举办的第五届“解放军总医院—麻省理工学院医疗大数据学术交流及 Datathon 活动”会前培训班于线上圆满收官&#xff0c;和鲸科技为会前培训班提供全程技术平台支持&#xff0c;该培训班…

掌握 4个SD 卡数据恢复技巧,避免数据丢失!

SD 卡作为一种常见的存储设备&#xff0c;里面通常存放着完美的照片、视频、文档等重要数据。但是&#xff0c;在生活中SD 卡数据丢失的情况时有发生&#xff0c;非常令人崩溃。那今天咱们就来讨论一下4个有效恢复SD卡数据的方法&#xff01; 1、福昕estore 直通车&#xff1a…

软硬链接和动静态库

为什么一定要提供路径呢&#xff1f; 因为要根据路径找到文件 一切与路径相关的问题都是方便用户去访问文件 软硬链接 给我康康 软链接是这样的&#xff1a; ln -s file_target1.txt file_soft.link 软链接有独特的innode 这是硬链接&#xff1a; ln file_target2.txt …

免费【2024】springboot 高校毕业生离校管理系统的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…