c++模板入门

c++系列模板入门


文章目录

  • c++系列模板入门
  • 一、模板概念引入
  • 二、函数模板
    • 2.1、函数模板的概念
    • 2.2、函数模板的定义格式
    • 2.3、函数模板的使用
  • 三、类模板
    • 1.1、什么是类模板
    • 1.2、类模板的定义格式
    • 1.3、类模板于函数模板的区别


一、模板概念引入

在程序设计中我们经常需要对两个数据进行交换,对于不同的数据类型,我们就需要重载不的函数。

void Swap(int& left, int& right){int temp = left;left = right;right = temp;} 
void Swap(double& left, double& right){double temp = left;left = right;right = temp;}

问:面对这些逻辑相同,仅是类型不同的程序,我们该如何更好的实现他们呢?

答:如果有一个模具,通过给这个模具中填充不同材料(类型),来获得不同材料的铸件(生成具体类型的代码),那我们将会方便很多,为完成这一问题C++产生了泛型编程的思想。
泛型编程:允许函数和数据结构使用任何数据类型,而不需要为每种数据类型编写重复的代码。模板是泛型编程的基础。
模板——是一段带有类型参数的程序代码,可以通过给这些参数提供一些类型来得到针对不同类型的具体代码。

二、函数模板

2.1、函数模板的概念

函数模板并不是一个可以直接使用的函数,它实际上是定义一个通用函数,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)均被作为参数:不指定具体类型,而是用一个虚拟 的类型来代替(实际上是用一个标识符来占位)。凡是函数体相同的函数都可以用这个模板来代替,在函数调用时根据传入的实参来逆推出真正的类型(逆推过程由编译器来完成),从而来实现代码的复用。这个通用函数就称为函数模板(函数模板不是一个实在的函数,编译器不能为其生成可执行代码)。

2.2、函数模板的定义格式

template<class / typename T1,......,class / typename Tn> typename用来定义模板参数关键字,也可以使用class,在这里他们两个的作用并无区别,T1....Tn均为类型占位符。

 template<typename T>//简单函数模板void Swap( T& left,  T& right){T temp = left;left = right;right = temp;}

2.3、函数模板的使用

以两数相加函数为例,我们在进行不同类型对象间的数据相加问题时,就不需要重写多个函数 例:

template<class T1>
T1 add(T1 x,T1 y)//T1类型占位符,编译器推演出合适的类型将他替换
{return x + y;
}
int main()
{int a1 = 1;int a2 = 2;double a3 = 1.1;double a4 = 2.1;cout << add(a1, a2) << endl;cout << add(a3, a4) << endl;return 0;

运行结果:

在这里插入图片描述
在使用函数模板时,我们只需要传递实参,编译器会自动推演出合适的类型。
在这里插入图片描述
可以看到,即使存在模板还是可以定义,具体的函数的,编译器在生成函数之前,首先会去,局部、全局找是否有合适的函数,如果有则调用已存在的,否则生成函数(这里double类型就没有合适的,所以调用生成函数)。
在这里插入图片描述
在这里插入图片描述
通过上面两张图我们可看到,我将模板屏蔽后代码是可以执行的,这是因为,我们自己定义的函数,支持隐式类型转换(从打印结果可以看到,从在数据丢失问题),当我们,将自定义函数屏蔽后,成序出错,这是因为,我们只声明了一个类型占位符,编译不知道将他推演成什么类型(间接反映出,编译器生成的函数,不支持隐式类型转换)。

对于这个问题,我们有三种方法解决:
1.在传递实参时,进行显示类型转换

   cout << add(a1,(int) a4) << endl;

2.在原模板上,增加一个模板参数

template<class T1,class T2>
T1 add(T1 x,T2 y){}//这里函数体省略了

3.模板显示实例化

   cout << add<int>(a1, a4) << endl;

具体改变大家可以用代码跑一下

三、类模板

1.1、什么是类模板

类模板是一种用来生成类定义的模板,其中可以包含一个或多个类型参数。这些类型参数可以在定义类的时候替换为任意类型,从而使得我们能够创建适用于多种数据类型的通用类定义。类模板的定义使用 template < class T> 或 template< typename T> 来声明一个类型参数(可以声明多个)。

1.2、类模板的定义格式

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

我们以这个简单的线性表为例,进行讲解

template<class T>
class Vector
{
public:Vector(size_t capacity = 10): _pData(new T[capacity]),_size(0),_capacity(capacity){}// 使用析构函数演示:在类中声明,在类外定义。~Vector();void PushBack(const T& data)void PopBack()size_t Size() { return _size; }T& operator[](size_t pos){assert(pos < _size);return _pData[pos];}
private:T* _pData;size_t _size;size_t _capacity;
};
// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{if (_pData)delete[] _pData;_size = _capacity = 0;
}

在对类模板进行定义时,类的成员函数一样可以使用,模板参数精选模板定义。

1.3、类模板于函数模板的区别

类模板不同于函数模板,它没有自动类型推导的使用方式,类模板在使用时,只能使用显示定义的方式 例:

//使用类模板创建对象Vector<int> v1;vector<double> v2;

这里我们要知道,类名(vector)并不是所创建对象的类型,只有对象被实力出来,它才具有类型(vector< int>、vector< double>).

类模板可以有,默认参数类型例:

template<class T1, class T2, ..., class Tn=int>//默认参数类型 
class 类模板名
{// 类内成员定义
}; 

这里同定义函数时,使用缺省参数,原理相同。

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

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

相关文章

谷粒商城のsentinelzipkin

文章目录 前言一、Sentinel1、什么是Sentinel2、项目配置3、使用案例3.1、流控3.2、降级3.3、黑白名单设置 二、Zipkin1、什么是Zipkin2、项目配置3、整合案例 前言 本篇介绍Spring Cloud Ali的sentinel组件&#xff0c;用于对微服务的熔断降级&#xff0c;以及链路追踪zipkin的…

Freertos学习日志(1)-基础知识

目录 1.什么是Freertos&#xff1f; 2.为什么要学习RTOS&#xff1f; 3.Freertos多任务处理的原理 1.什么是Freertos&#xff1f; RTOS&#xff0c;即&#xff08;Real Time Operating System 实时操作系统&#xff09;&#xff0c;是一种体积小巧、确定性强的计算机操作系统…

2. Flink快速上手

文章目录 1. 环境准备1.1 系统环境1.2 安装配置Java 8和Scala 2.121.3 使用集成开发环境IntelliJ IDEA1.4 安装插件2. 创建项目2.1 创建工程2.1.1 创建Maven项目2.1.2 设置项目基本信息2.1.3 生成项目基本框架2.2 添加项目依赖2.2.1 添加Flink相关依赖2.2.2 添加slf4j-nop依赖2…

TIA 中用 GSD 方式组态 ET200SP 安全模块时如何用 S7-FCT 分配安全目标地址

1 概述 用 GSD 方式组态的 ET200SP 的分布式从站上&#xff0c;现在可以使用安全模块&#xff08;早期 是无法支持&#xff09;&#xff0c;这种用法对 ET200SP 接口模块的版本和编程软件的版本都有要求。 ET200SP 故障安全模块可通过 GSD 文件用于以下接口模块&#xff1a; …

0,国产FPGA(紫光同创)-新建PDS工程

国产FPGA正在蓬勃发展&#xff0c;紫光同创FPGA是大家竞赛时经常遇到的一款国产FPGA&#xff0c;本专栏从IP核开始一直到后续图像处理等。 开发板&#xff1a;盘古50K标准板 1&#xff0c;新建PDS工程 点击File&#xff08;1&#xff09;&#xff0c;然后是New Projects&#…

视频Qoe测量学习笔记(一)

目录 流媒体协议详解 RTSP&#xff1a;实时流式协议 RTCP&#xff1a;实时运输控制协议 RTP&#xff1a;实时运输协议 H.264 流媒体协议详解 RTSP&#xff1a;实时流式协议 由IETF MMusic小组开发&#xff0c;已成为互联网建议标准[RFC 2326]。RTSP本身并不传送数据&…

计算机视觉常用数据集Foggy Cityscapes的介绍、下载、转为YOLO格式进行训练

我在寻找Foggy Cityscapes数据集的时候花了一番功夫&#xff0c;因为官网下载需要用公司或学校邮箱邮箱注册账号&#xff0c;等待审核通过后才能进行下载数据集。并且一开始我也并不了解Foggy Cityscapes的格式和内容是什么样的&#xff0c;现在我弄明白后写下这篇文章&#xf…

单向函数、单向陷门函数、困难问题

1、单向函数 设函数 yf(x) &#xff0c; 对于给定的x&#xff0c;计算出y很容易&#xff1b;对于给定的y&#xff0c;计算出x很难。 2、单向陷门函数 设函数 yf(x) &#xff0c;且f有陷门&#xff0c; 对于给定的x&#xff0c;计算出y很容易&#xff1b;对于给定的y&#…

js 获取当前时间与前一个月时间

// 获取当前时间的毫秒数 var currentTimeMillis new Date().getTime();// 获取前一个月的Date对象 var dateLastMonth new Date(); dateLastMonth.setMonth(dateLastMonth.getMonth() - 1);// 获取前一个月的毫秒数 var timeMillisLastMonth dateLastMonth.getTime();conso…

Linux_02 Linux常用软件——vi、vim

vi编辑器有三种主要模式&#xff0c;每种模式的功能和用途不同&#xff1a; 一、命令模式 (Command Mode)&#xff1a; - 启动 vi 时默认进入此模式。 - 你可以在此模式下移动光标&#xff0c;输入各种命令&#xff08;如删除、复制、粘贴等&#xff09;。 yy&#xff1a;…

C++设计模式结构型模式———装饰模式

文章目录 一、引言二、装饰器模式三、总结 一、引言 装饰模式是一种结构型设计模式&#xff0c; 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 该模式展现出了运行时的一种扩展能力&#xff0c;以及比继承更强大和灵活的设计视角和设计能力&#x…

「iOS」——知乎日报一二周总结

知乎日报仿写 前言效果Manager封装网络请求线程冲突问题下拉刷新添加网络请求的图片通过时间戳和日期格式化获取时间 总结 前言 前两周内容的仿写&#xff0c;主要完成了首页的仿写&#xff0c;进度稍慢。 效果 Manager封装网络请求 知乎日报的仿写需要频繁的申请网络请求&am…

Profinet、Ethernet/IP 工业以太网无线通信解决方案

在工业现场&#xff0c;我们常常会面临这样的困扰&#xff1a;两个PLC之间、PLC 跟远程IO之间或者PLC 跟伺服之间由于种种原因不方便布线&#xff0c;严重影响了通讯效率和生产进程。为了解决这一难题&#xff0c;三格电子设计了一款工业以太网无线网桥&#xff0c;这款无线网桥…

【数据结构】二叉树——前中后序遍历

一、如何遍历二叉树 以图上这个二叉树作为例子&#xff0c;我们若想要访问二叉树中每一个元素 我们一般是采用递归的方式 比如我们要访问完整个二叉树&#xff0c;我们进行递归先访问根的左子树&#xff0c;然后因为递归再次调用&#xff0c;我们会先一直访问二叉树左子树&…

桑基图在医学数据分析中的更复杂应用示例

桑基图&#xff08;Sankey Diagram&#xff09;能够有效地展示复杂的流动关系&#xff0c;特别适合用于医学数据分析中的多种转归和治疗路径的可视化。接下来&#xff0c;我们将构建一个稍微复杂的示例&#xff0c;展示不同疾病患者在治疗过程中的流动&#xff0c;以及他们的治…

WPS 表格奇数行或偶数行填充颜色(Excel也适用)

今天在做项目测试用例&#xff0c;全都是白色底纹&#xff0c;日以继夜的赶项目 大家都头脑不清晰了&#xff0c;看着容易错行&#xff0c;看我一键更新 如本次测试用例&#xff0c;单元格区域的奇数行填充灰色。 点击单元格最左上角选定区域&#xff0c;然后依次点击【开始】…

RT-DETR:替代YOLO的更快实时对象检测模型(附代码)

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

JavaScript。—关于语法基础的理解—

一、程序控制语句 JavaScript 提供了 if 、if else 和 switch 3种条件语句&#xff0c;条件语句也可以嵌套。 &#xff08;一&#xff09;、条件语句 1、单向判断 &#xff1a; if... &#xff08;1&#xff09;概述 < if >元素用于在判断该语句是否满足特定条…

ComfyUI - ComfyUI 工作流中集成 SAM2 + GroundingDINO 处理图像与视频 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/143359538 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 SAM2 与…

Android13预置应用及授权开发

在android13中&#xff0c;要预置一个对讲应用&#xff0c;从预置和授权&#xff0c;梳理了一下&#xff0c;以便后续查询使用。在此记录 一放置应用 我的apk应用放在vendor下面&#xff0c; 路径&#xff1a;projectroot/vendor/fly/package/apps/DMR/flydmr.apk (vendor/fl…