c++----初识模板

        大家好,这篇博客想与大家分享一些我们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.rhkb.cn/news/394818.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GIS,矢量瓦片加载速度优化

文章目录 一、前言二、矢量瓦片的基础知识三、矢量切片加载速度优化3.1 地图缩编3.2 矢量瓦片中的图层根据显示层级定制3.3 矢量瓦片中的图层字段要按需定制3.4 多个图层合并为矢量切片图层组发布 四、总结 一、前言 单个矢量瓦片的大小并没有固定的上限&#xff0c;这意味着在…

C语言典型例题30

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 习题2.7 从银行贷了一笔款d&#xff0c;准备每月还款额为p&#xff0c;月利率为r&#xff0c;计算多少个月能还清。 设d30000元&#xff0c;p6000元&#xff0c;r1%。对求得的月份取小数点后一位&#xff0c;对第二…

Spring面试篇章——IOC

IOC概念和原理 IOC概念 IOC就是控制反射&#xff0c;把对象创建和对象之间的调用过程&#xff0c;交给Spring进行管理使用IOC的目的&#xff1a;降低耦合度 IOC底层原理 xml解析、工厂模式、反射 图解&#xff1a; 原始模式 耦合度太高了&#xff0c;即当dao改了&#xf…

【Liunx】线程与进程的经典面试题总结

在这个浮躁的时代 只有自律的人才能脱颖而出 -- 《觉醒年代》 线程与进程的面试题总结 1 简述什么是LWP2 简述LWP与pthread_create创建的线程之间的关系3 简述轻量级进程ID与进程ID之间的区别4 请简述什么是线程互斥&#xff0c;为什么需要互斥5 简述你了解的进程间通信方式…

360安全大模型为什么是“非卖品”?

大模型虽然不是万能的&#xff0c;但是没有大模型又是万万不能的。以AI大模型为动力引擎&#xff0c;AI正在重塑各行各业&#xff0c;并快速“飞入寻常百姓家”。 AI安全 以“模”制“模” 2024年全国两会&#xff0c;“人工智能”首次被写入政府工作报告。报告中提出&#xff…

【2024算力大会分会 | SPIE出版】2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024)

【2024算力大会分会 | SPIE出版】 2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024) 2024 International conference on Cloud Computing, Performance Computing and Deep Learning CCPCDL往届均已完成EI检索&#xff0c;最快会后4个半月完成&#xff01; 2024中…

嵌入式学习之文件IO和标准IO

IO概述 I/O是Input/Output的缩写&#xff0c;指的是输入/输出。在计算机科学和工程领域&#xff0c;I/O是指计算机系统与外部环境或内部组件之间进行数据交换的过程和机制。 用户I/O 用户通过输入设备与计算机交互。例如&#xff0c;通过键盘输入文字、通过鼠标点击界面等。…

图片怎么裁剪成想要的尺寸?图片裁剪的几个常用方法

裁剪图片到精准且令人满意的尺寸&#xff0c;是每一位图像编辑爱好者、社交媒体达人以及专业设计师在日常工作中不可或缺的技能。在这个视觉为王的时代&#xff0c;一张完美适配各种平台的图片&#xff0c;能够瞬间抓住观众的眼球&#xff0c;传递出最精准的信息与情感。从手机…

Vue3项目创建及相关配置

Vue是一种用于构建用户界面的JavaScript框架。它采用了一种称为MVVM&#xff08;Model-View-ViewModel&#xff09;的架构模式。 MVVM是一种将用户界面与业务逻辑和数据分离的设计模式。它包括三个部分&#xff1a; Model&#xff08;模型&#xff09;&#xff1a;表示应用程序…

混合现实技术在虚拟培训、销售展示及教育科研等领域的应用方向

混合现实技术是虚拟现实技术的进一步发展方向&#xff0c;与传统的沉浸式虚拟现实技术相比混合现实技术能够为用户提供更多元化的观看场景。通过将虚拟物体与现实世界融合的全新形式为&#xff0c;包括虚拟训练、产品销售、教育科研等领域赋能。 混合现实技术中最为重要的是显示…

【JUC】并发编程与源码分析 1-7章

1 线程基础知识复习 1把锁&#xff1a;synchronized&#xff08;后面细讲&#xff09; 2个并&#xff1a; 并发&#xff08;concurrent&#xff09;&#xff1a;是在同一实体上的多个事件&#xff0c;是在一台机器上“同时”处理多个任务&#xff0c;同一时刻&#xff0c;其…

程序员保碗之策

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 1. **持续深化技术实力&#xff1a;从基础到前沿**夯实基础紧跟技术前沿跨领域融合 2. **提升实战能力&#xff1a;从项目到产品**参与实际项目自主实践产品思维 3. **建立个人品牌与影响力&#xff…

vs+qt一些问题

一直遇到的两个问题&#xff0c;今天解决了 1、 因为前后端分离&#xff0c;前端写完了&#xff0c;后端还在一直修改&#xff0c;但是每次都是单独打开的后端的sln&#xff0c;所以会出现这个&#xff0c;把前端的模块删掉就好了。 2、打开vs项目&#xff0c;很多报错&#…

sql注入靶场sqli-labs常见sql注入漏洞详解

目录 sqli-labs-less1 1.less1普通解法 1.在url里面填写不同的值&#xff0c;返回的内容也不同&#xff0c;证明&#xff0c;数值是进入数据库进行比对了的&#xff08;可以被注入&#xff09; 2.判断最终执行的sql语句的后面还有内容吗&#xff0c;并且能够判断是字符型的拼接…

MySQL:VIEW视图

概述 MySQL 视图&#xff08;View&#xff09;是一种虚拟存在的表&#xff0c;同真实表一样&#xff0c;视图也由列和行构成&#xff0c;但视图并不实际存在于数据库中。行和列的数据来自于定义视图的查询中所使用的表&#xff0c;并且是在使用视图时动态生成的。 数据库中只…

Unity物理模块 之 2D效应器

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​ 1.什么是效应器 2D 效应器 - Unity 手册 2D 效应器是与 2D 碰撞器一起使用的组件&#xff0c;相当于预先编写好的插…

⭕️【论文阅读】《Interactive Class-Agnostic Object Counting》

[2309.05277] Interactive Class-Agnostic Object Counting (arxiv.org) code&#xff1a; cvlab-stonybrook/ICACount: [ICCV23] Official Pytorch Implementation of Interactive Class-Agnostic Object Counting (github.com) 目录 Abstract Abstract 我们提出了一个新…

【合并 K 个升序链表】python刷题记录

R4-分治篇 目录 最小堆方法 分治法 ps: 如果只是数组就很好处理了 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def mergeKLists(self, lists…

Spring AOP 源码剖析

一.AOP基础概念 切面&#xff08;Aspect&#xff09;&#xff1a;切面是跨越多个类的关注点模块化&#xff0c;如事务管理。切面由切点和通知组成。连接点&#xff08;Join Point&#xff09;&#xff1a;在程序执行过程中某个特定的点&#xff0c;如方法调用或异常抛出。在Sp…

kafka基础概念二

1.Kafka中主题和分区的概念 1.主题Topic 主题-topic在kafka中是一个逻辑的概念&#xff0c;kafka通过topic将消息进行分类。不同的topic会被订阅该topic的消费者消费 但是有一个问题&#xff0c;如果说这个topic中的消息非常非常多&#xff0c;多到需要几T来存&#xff0c;因…