【C++基础(十)】C++泛型编程--模板初阶

news2025/1/13 3:07:47

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C++从入门到精通⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习C++
  🔝🔝


在这里插入图片描述

模板

  • 1. 前言
  • 2. 函数模板
  • 3. 函数模板原理
  • 4. 函数模板实例化
  • 5. 函数模板参数的匹配规则
  • 6. 类模板
  • 7. 类模板的实例化
  • 8. 总结以及拓展

1. 前言

在学习数据结构时会遇见以下的情况
数据结构中存储的类型往往不能确定
所以在实现数据结构时往往是这样做的

typedef int DateType

在写代码时用DateType来表示类型
如果想存储浮点型只需将int改为float

但是这样写会遇见一个问题:
写好数据结构类后在创建对象时
此.cpp文件只能创建一种类型的对象
对象存储的全是int/char/double类型
不能同时创建存储int的和char的对象

Data d1;//存储的int类型
Date d2;//存储的char类型

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

本章重点:

本篇文章重点讲解函数模板
和类模板的使用以及特性


2. 函数模板

请看以下函数代码:

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;
}

这样写非常的麻烦
使用模板可以使代码通用于不同类型:
swap函数模板:

template<typename T>
void Swap( T& left, T& right)
{
	T temp = left;
	left = right;
	right = temp;
}

写好上面的代码后,传int类型进去
T就会被实例化为int,以此类推

template和typename是规定
好了必须这样写,T是自己取的名字
其中,typename可以用class替换
并且一次性可以定义多个类型:

template<class T1,typename T2,class T3>

3. 函数模板原理

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器

在这里插入图片描述

在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此

可以用下面这张图来理解:

在这里插入图片描述


4. 函数模板实例化

  1. 隐式实例化

让编译器根据实参推演模板参数实际类型

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, a2);
	 Add(d1, d2);
 }

第一次调用的T被推演为int类型
第二粗调用的T被推演为double

不能这样写代码:

Add(a1, d1);

系统根据a1推演出T是int类型
但是d1是double类型不能用int
类型的参数啦接受,所以会报错


  1. 显示实例化

在函数名后的<>中指定模板参数的类型

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

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


5. 函数模板参数的匹配规则

模板函数和普通函数可以同时存在:

// 专门处理int的加法函数
int Add(int left, int right)
{
 	return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right)
{
 	return left + right;
}

在调用函数时若参数和非模板函数匹配
那么编译器会优先调用非模板函数
若非模板函数不匹配或模板函数更匹配
那么编译器会优先调用模板函数

Add(10,20)//调用非模板
Add(11.1,6.3);//调用模板

6. 类模板

类模板的应用非常广泛
像开头提到的数据结构问题

类模板的定义格式:

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

和函数模板类似,类模板也可以同时
定义多个模板参数

写一个简易的顺序表:

template<class T>
class Vector
{ 
public :
 Vector(size_t capacity = 10)
 : _Data(new T[capacity])
 , _size(0)
 , _capacity(capacity)
 {}
 T& operator[](size_t pos)
 {
	 assert(pos < _size);
	 return _Data[pos];
 }
 
private:
 T* _Data;
 size_t _size;
 size_t _capacity;
};

所有实际类型需要出现的地方用T代替


7. 类模板的实例化

和函数模板不同,类模板没有隐式推演
用户必须显示实例化

Vector<int> v1;

注意:
Vector是类名
Vector< int >才是类型

当在类中声明一个函数
但是想在类外定义时
若函数的参数或内部使用的类型
和模板有关系,那么必须这样写:

template<class T>
class Vector
{ 
public :
    //类中声明函数
	void push_back(T x);
private:
 T* _Data;
 size_t _size;
 size_t _capacity;
};

类外定义:

template<class T>
void Vector<T>::push_back(T x)
{
	_Date[_size] = x;
	_size++;
}

注:必须要再加上类模板template
并且要指定类域


8. 总结以及拓展

泛型编程是C++的一大利器
它极大的减少了代码的复杂程度
并且增加了代码的可读性

C++基础部分的内容已经全部结束
下一阶段进入C++中阶:STL的使用

在这里插入图片描述

拓展:

泛型编程拓展阅读


🔎 下期预告:STL库的介绍以及使用 🔍

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

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

相关文章

2023年中国倍率型磷酸铁锂出货量及市场需求分析:插电混动汽车用电池为第一大应用市场[图]

由于新能源锂电池市场的竞争极其激烈&#xff0c;各大电池生产厂商不得不细化研发方向&#xff0c;抢占竞争者少、营利性高的细分专业赛道。因此&#xff0c;“自定义”型单体电池应运而生。其主要分为三个大类&#xff0c;分别为高倍率型电池、长寿命型电池和大容量型电池。这…

Linux安装Oracle数据库!

第一步&#xff0c;调试Linux虚拟机启动&#xff1a; 打开后&#xff0c;报错&#xff0c;如图&#xff1a; 解决&#xff1a; 步骤1&#xff1a;用管理员身份启动cmd&#xff0c;输入&#xff1a;bcdedit 查看hyper-v的状态&#xff0c;这里应该是off关闭状态。 步骤2&#…

cuda+anaconda+pytorch按照教程

首先安装显卡对应的CUDA版本&#xff0c;关键点在于区别显卡支持的CUDA最高版本和运行版本 1、查看当前显卡支持的最高版本&#xff0c;有两种方式&#xff1a; 1&#xff09;NVIDIA控制面板—>帮助—>系统信息—>组件—>NVCUDA.dll对应版本 请注意&#xff0c;12…

Java的switch语句块

说明 Java的switch语句块可以用于多个分支的判断执行。每个case分支执行完后&#xff0c;要么退出方法体&#xff08;用return语句&#xff09;、要么退出switch语句块&#xff08;用break语句&#xff09;、要么继续往下执行。但如果一个case执行完后&#xff0c;要继续执行下…

jQuery使用(超详细)

一、jQuery介绍 二、jQuery的简单使用 <head><meta charset"utf-8"><title></title><script type"text/javascript" src"../js/jquery-1.10.2.min.js"></script><script type"text/javascript"…

安装使用IDEA,修改样式,配置服务,构建Maven项目(超级详细版)

目录 前言&#xff1a; 一&#xff0c;安装 1.1打开官网JetBrains: Essential tools for software developers and teams点击 Developer Tools&#xff0c;再点击 Intellij IDEA 2.点击下载​编辑 3.选择对应的版本&#xff0c;左边的 Ultimate 版本为旗舰版&#xff0c;需要…

分割一切模型 Fast SAM C++推理部署---onnxruntime(有核心代码)

Fast SAM C推理部署—onnxruntime 核心源代码在结尾处 晓理紫 0 XX开局一张图&#xff0c;剩下… 本文记录只为日后更好学习 1 Fast SAM 简介 Fast SAM是仅使用SAM作者发布的SA-1B数据集的2%进行训练的CNN任意分割模型。FastSAM的性能与SAM方法相当&#xff0c;运行速度提高了…

概率论与数理统计:第二、三章:一维~n维随机变量及其分布

文章目录 Ch2. 一维随机变量及其分布1.一维随机变量1.随机变量2.分布函数 F ( x ) F(x) F(x)(1)定义(2)分布函数的性质 (充要条件)(3)分布函数的应用——求概率3.最大最小值函数 2.一维离散型随机变量及其概率分布(分布律)3.一维连续型随机变量及其概率分布(概率密度)4.一般类型…

Linux基础篇(五)文件权限

目录 一、文件权限的概念 二、Linux命令ll的结果解析 三、Linux修改权限的两种方法 四、更改文件的拥有者和所属组 五、身份的判定 六、系统掩码 七、删除文件需要的权限 八、粘滞位 一、文件权限的概念 1.是什么&#xff1f; 简单地说就是什么身份的用户能对文件做什么事。 …

如何在CSS中水平居中一个元素?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用 margin: 0 auto⭐ 使用 Flexbox 布局⭐ 使用绝对定位和负边距⭐ 使用表格布局⭐ 使用网格布局⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅…

【密码学】密码棒密码

密码棒密码 大约在公元前700年,古希腊军队使用一种叫做scytale的圆木棍来进行保密通信。其使用方法是这样的:把长带子状羊皮纸缠绕在圆木棍上,然后在上面写字;解下羊皮纸后,上面只有杂乱无章的字符,只有再次以同样的方式缠绕到同样粗细的棍子上,才能看出所写的内容。快速且不容…

STM32定时器TIM控制

一、CubeMX的设置 1、新建工程&#xff0c;进行基本配置 2、配置定时器TIM2 1&#xff09;定时器计算公式&#xff1a;&#xff08;以下两条公式相同&#xff09; Tout ((ARR1) * PSC1)) / Tclk TimeOut ((Prescaler 1) * (Period 1)) / TimeClockFren Tout TimeOut&…

选读SQL经典实例笔记23_读后总结与感想兼导读

1. 基本信息 SQL经典实例 SQL Cookbook [美]安东尼莫利纳罗&#xff08;Anthony Molinaro&#xff09; / 人民邮电出版社 / 2018-07 / 其他 人民邮电出版社,2018年7月出版第1版&#xff0c;2021年12月出版第2版 1.1. 读薄率 1版书籍总字数827千字&#xff0c;笔记总字数30…

sharedPreferences的使用之按钮状态切换的保存

什么是sharedPreferences&#xff1f;有什么用 SharedPreference是Android开发中一个轻量级的数据存储的方式&#xff0c;除了它还有SQLite数据库。它可以将数据以键值对的形式存放到文件中&#xff0c;在需要的时候再取出来使用。相比于去操作数据库&#xff0c;对于一些简单…

缓存穿透,击穿,雪崩之间的区别与联系

1、缓存数据基本流程 通常来说,我们是从数据库将数据查询出来之后,如果数据不为空,则将数据存储在缓存中,下次查询时就直接从缓存查询了,只有查询不到才会从数据库查询。 2、缓存穿透 核心在穿透两个字,穿透了,就说明在查询数据时没有遇到阻碍,直接就查询到了数据库。…

Spring-Cloud-Loadblancer详细分析_2

LoadBalancerClients 终于分析到了此注解的作用&#xff0c;它是实现不同服务之间的配置隔离的关键 Configuration(proxyBeanMethods false) Retention(RetentionPolicy.RUNTIME) Target({ ElementType.TYPE }) Documented Import(LoadBalancerClientConfigurationRegistrar…

记录--浏览器渲染15M文本导致崩溃怎么办

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 最近&#xff0c;我刚刚完成了一个阅读器的txt文件阅读功能&#xff0c;但在处理大文件时&#xff0c;遇到了文本内容过多导致浏览器崩溃的问题。 一般情况下&#xff0c;没有任何样式渲染时不会出现什…

《全生命周期眼健康管理》助力健康科学用眼

8月8日下午&#xff0c;烟台正大光明眼科医院眼健康管理中心张提主任受邀来到烟台市残疾人事务综合服务中心&#xff0c;为残联康复训练教师及相关工作人员进行了《全生命周期眼健康管理》讲座。 烟台正大光明眼科医院眼健康管理中心张提主任 “全生命周期眼健康”这一理念其宗…

u盘为什么提示格式化?u盘提示格式化怎么办

U盘是一种便携式存储设备&#xff0c;在使用U盘的过程中&#xff0c;有时候会出现提示需要格式化的情况。这种情况通常会让人担心自己重要的数据是否会丢失。那么&#xff0c;U盘为什么提示格式化&#xff1f;U盘提示格式化怎么办&#xff1f;在本文中&#xff0c;我们将探讨U盘…

80. 删除有序数组中的重复项 II

题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 解题思路&#xff1a;因为数组有序&#xff0c;相等的元素一定相邻&#xff0c;所以可以使用一个变量num统计相等元素的个数&#xff0c;如果当前元素和前一个元素相等&#xff0c…