C++模板(初阶)

1.引入

在之前的笔记中有提到:函数重载(特别是交换函数(Swap)的实现)

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;
}
void Swap(char& left, char& right)
{char temp = left;left = right;right = temp;
}
使用函数重载虽然可以实现,但是有一下几个不好的地方:
1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数;
2. 代码的可维护性比较低,一个出错可能所有的重载均出错;

总之:实在麻烦,而且代码结构相似,也就有了模板的概念:(告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码

2.模板

泛型编程:

编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础

1.函数模板

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生 函数的特定类型版本

格式:

template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表){}

或者: 

template<class T1, class T2,......,class Tn>
返回值类型 函数名(参数列表){}

EG:

template<typename T>//template<class T>
void Swap(T& left, T& right)
{T temp = left;left = right;right = temp;
}
注意: typename 用来定义模板参数 关键字 也可以使用 class( 切记:不能使用 struct 代替class)
函数模板原理:
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具, 所以其实模板就是将本来应该我们做的重复的事情交给了编译器
在编译器编译阶段 ,对于模板函数的使用, 编译器需要根据传入的实参类型来推演生成对应 类型的函数 以供调用。比如: 当用 double 类型使用函数模板时,编译器通过对实参类型的推演, T 确定为 double 类型,然后产生一份专门处理 double 类型的代码 ,对于字符类型也是如此
函数模板的实例化:
用不同类型的参数使用函数模板时 ,称为函数模板的 实例化;
模板参数实例化分为: 隐式实例化 和显式实例化;

隐式实例化:让编译器根据实参推演模板参数的实际类型

template<class T>
T Add(const T& left, const T& right)
{return left + right;
}
int main()
{int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add(a1, d1);//报错return 0;
}
该语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型通过实参a1 T 推演为 int ,通过实参 d1 T 推演为 double 类型,但模板参数列表中只有一个T ,编译器无法确定此处到底该将T 确定为 int 或者 double 类型而报错;
注意:在模板中,编译器一般不会进行类型转换操作(隐式类型转换),因为一旦转化出问题,编译器就需要背黑锅;

因此,当出现编译器不能自我判断的时候:有两种解决办法:

1.强制转换;Add((double)a1, d1);

2.显示实例化;

显式实例化:在函数名后的<>中指定模板参数的实际类型

int main(void)
{int a = 10;double b = 20.0;// 显式实例化Add<int>(a, b);return 0;
}

如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错 

注意:如果程序中除了函数模板,还有同名函数(调用传参实现),会优先调用这个同名函数(别人请客干嘛自己煮饭呢)

2.类模板 

格式:

template<class T1, class T2, ..., class Tn>//或者template T1....
class 类模板名
{
// 类内成员定义
};
#include<iostream>
using namespace std;
// 类模版
template<typename T>
class Stack
{
public:Stack(size_t capacity = 4){_array = new T[capacity];_capacity = capacity;_size = 0;}~Stack(){delete[] _array;_array = nullptr;_size = _capacity = 0;}void Push(const T& data);
private:T* _array;size_t _capacity;size_t _size;
};
// 模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误
template<class T>
void Stack<T>::Push(const T& data)
{// 扩容_array[_size] = data;++_size;
}
int main()
{Stack<int> st1; // intStack<double> st2; // doublereturn 0;
}

注意:模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误;

st1,st2不是new出来的,不需要delete,出了局部域会调用析构函数

只有:Stack<double>* pst = new Stack<double>; 才要去调用delete

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

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

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

相关文章

小程序开发_02

一、项目的基本结构 二、小程序的页面组成部分 三、json配置文件 ① project.config.json文件 作用&#xff1a;项目的配置文件&#xff0c;用来记录对小程序开发工具所作的个性化配置 ② sitemap.json 作用&#xff1a;是否允许被微信引擎搜索,不希望被搜索dis ③ app.jso…

notes for datawhale summer camp chemistry task2

[[appendix/Task2_RNN.ipynb|Task2_RNN.ipynb]] 本次的任务是进一步了解 AI4Science 相关知识&#xff0c;然后使用深度学习的方法建模。 你可以从中&#xff1a;了解一些相关历史、了解 SMILES 和分子指纹&#xff0c;并对 RDkit 工具包有更深的认识&#xff1b;探究深度学习…

基于C51和OLED12864实现贪吃蛇小游戏

引言 在微电子技术飞速发展的今天&#xff0c;单片机作为智能控制的核心&#xff0c;广泛应用于各种电子设备中。C51系列单片机以其高效、稳定的特性&#xff0c;成为众多电子爱好者和工程师的首选平台。而OLED显示屏以其轻薄、低功耗、响应速度快等优点&#xff0c;在显示设备…

设计模式 策略模式(Strategy Pattern) C++表达

设计模式 策略模式&#xff08;Strategy Pattern&#xff09; C表达 flyfish 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为设计模式&#xff0c;它的核心思想是将一系列相关的算法或行为封装到独立的策略类中&#xff0c;并使得这些策略可以相互替换。主要用…

线性回归和逻辑回归API

1. 线性回归&#xff08;Linear Regression&#xff09; 主要类 LinearRegression: 这是scikit-learn中用于实现线性回归的类。 用法 from sklearn.linear_model import LinearRegression# 创建模型实例 model LinearRegression()主要参数 fit_intercept: 默认为True。是…

遇到的问题123

1.update:visible更新数据不生效 父组件传递的visible值不是ref定义的响应值&#xff0c;要加v-model修饰符 v-model:visible"chartsConfig.visible"

测试面试宝典(三十五)—— fiddler的工作原理

Fiddler 是一款强大的 Web 调试工具&#xff0c;其工作原理主要基于代理服务器的机制。 首先&#xff0c;当您在计算机上配置 Fiddler 为系统代理时&#xff0c;客户端&#xff08;如浏览器&#xff09;发出的所有 HTTP 和 HTTPS 请求都会被导向 Fiddler。 Fiddler 接收到这些…

springcloud接入seata管理分布式事务

下载安装包 链接: seata 配置seata-server 文件上传Linux解压 压缩包我放在/usr/local/seata中 tar -zxvf seata-server-2.0.0.tar.gz修改配置文件 设置nacos为注册和配置中心 进入文件夹 cd /usr/local/seata/seata/conf修改application.yml文件 ...... ...... cons…

CST软件如何进行参数化扫描?

在用CST进行仿真设计的过程中&#xff0c;经常需要对某一些参数进行参数化设置&#xff0c;并对这些参数进行仿真对比。这一期&#xff0c;我们介绍下如何进行参数化扫描。 还是借用&#xff0c;之前已经对馈电位置、贴片的长和宽都进行了参数设置&#xff0c;如下图所示&…

计算机网络HTTP全讲解,让你透彻掌握HTTP协议(三)http长短连接/代理/网关/缓存/内容协商机制/断点续传

HTTP HTTP的长连接与短连接短链接长链接HTTP代理代理的作用HTTP网关web网关常见的网关类型HTTP缓存HTTP缓存头部字段HTTP缓存工作方式缓存改进方案cdn缓存工作方式浏览器操作对http缓存的影响HTTP内容协商机制客户端驱动服务器驱动请求首部集近似匹配透明协商断点续传和多线程下…

深拷贝——JSON.stringify()序列化和JSON.prase()反序列化

为什么要使用深拷贝&#xff1f; 1、简单理解 JSON.parse() 和 JSON.stringify() 是 JavaScript 中用于处理 JSON 数据的两个内置方法 使用深拷贝的主要原因是为了创建一个对象或数组的完全独立副本&#xff0c;这样对副本的任何更改都不会影响到原始数据。 在 JavaScript …

springboot投票管理系统-计算机毕业设计源码33128

摘 要 本文介绍了基于微信小程序和Spring Boot的投票管理系统的设计与实现。该系统结合了移动互联网技术和后端开发框架&#xff0c;旨在为各类组织或活动提供一个高效、便捷、用户友好的在线投票平台。 系统采用微信小程序作为前端展示与交互界面&#xff0c;用户无需下载安装…

图片等比例缩放方案

图片等比例缩放方案 在Web开发时无可避免的需要将图片进行缩放&#xff0c;缩放时需要保证图片不变形&#xff0c;也就是需要等比例缩放。 设定宽度或高度 引入图片时&#xff0c;仅设置图片的width或者是height就可以使另一边自适应&#xff0c;从而实现等比例缩放。 <…

学校如何筹办一场汉字听写大赛

汉字作为中国最宝贵的文化遗产&#xff0c;在五千年的历史长河里&#xff0c;汉字以其浩瀚广博抒写着华夏历史&#xff0c;以其灵秀展示着炎黄之精神。传承汉字文明是我们的使命和主责任。随着科技的发展&#xff0c;现在人们很少用笔书写汉字&#xff0c;导致汉字听写能力普遍…

unity2D游戏开发16弹弓动画

清理动画器 选中PlayerObject,打开Animator,删除原来的四个状态 右键选择Create State |from New Blend Tree; 冲命名为Walk Tree 双击Walk Tree查看Blend Tree Graph 设置属性为2D Simple Directional,再点击加号选择Add Motion Field 添加四个,如图 点击Base Layer

Python面试整理-常用标准库

Python的标准库包含了大量的模块和包,支持各种编程任务,从文件处理、数据序列化,到网络编程等。这些模块预安装在Python中,无需额外安装就可以使用。以下是一些非常有用且常用的标准库模块: 1. os 用于与操作系统进行交互,包括文件和目录管理操作。 import os # 获取当前…

【数据结构】队列(链表实现 + 力扣 + 详解 + 数组实现循环队列 )

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;数据结构 &#x1f4da;本系列文章为个人学…

VSCode修改插件与缓存路径—究极版

一. 安装 安装的时候选中添加到资源管理器中&#xff0c;以便后续修改注册表。当然咱们自己手动建也是可以的 这样安装有个缺点&#xff0c;会在空白处、文件右键、目录右键创建通过VSCode打开。 但是在空白处打开就很不爽&#xff0c;所以删除注册表即可 计算机\HKEY_CLASS…

【WEB安全】 PHP基础文件知识完整教学中(超详细)

文章目录​​​​​​​ 1.PHP 文件处理 PHP 操作文件 PHP 文件打开/读取/关闭 ​​​​​​​文件的 复制 删除 重名 ​​​​​​​文件的判断 2.PHP获取文件属性 3.PHP目录操作 4.命名空间 PHP 命名空间可以解决以下两类问题&#xff1a; 5.正则表达式 正则表达…

python编程,设计一个详细的软件 与SADS 相似

软件功能模块&#xff1a; 用户界面模块&#xff08;UI Module&#xff09; 项目管理界面模型构建界面分析和设计界面结果展示和报告生成界面 数据库模块&#xff08;Database Module&#xff09; 材料数据库结构组件数据库设计标准和规范数据库用户项目数据存储 模型构建模块&…