【C++】——初识模板

news2024/9/21 14:31:28

目录

一、泛型编程

二、函数模板

        2.1 定义

        2.2 格式

        2.3 生成原理 

         2.4 实例化

                2.4.1  隐式实例化

                2.4.2 显式实例化

        2.5 匹配原则

三、类模板

                3.1 定义格式

        3.2 实例化


一、泛型编程

        什么是泛型编程,大家可思考这个问题:swap函数大家都会实现,那么我们要实现不同类型的该如何处理呢?大家这时不由得想到函数重载或者函数指针。但是,前者实现过于冗余,后者实现出来,咱们又看着不爽,但又和前者代码量差不多。所以,为了解决以上的问题,C++重磅推出了:泛型编程也就是——模板。

        模板分为:函数模板和类模板

二、函数模板

        2.1 定义

                在内容开始之前,大家且听一个小故事:

                屏幕前的各位都是勤奋好学之人,今日你仍像往常一样继续学习,可突然困了。当你再次醒来发现自己穿越了,成为了书店的店小二。书店老板的女儿肤白貌美的,符合你的审美,你不由得想得到其芳心。你突然注意到:书店所有的书都是手写的,效率低下。你身为现代人不由得想到了法子:我能不能把文章印到一个板子上,客人要什么,就印什么,这样不仅提高了效率,还能获得最大收益。你把想法告诉了老板,老板听后决定采取你的建议,结果大赚特赚。在此情景下把女儿许配给你,就在洞房花烛夜之时,你醒了过来。看到此文章,不由得对模板认识深刻了几分。

                相信大家此时对模板应该有了些认识,在C++中模板的定义如下:

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

                那么,我们该如何实现模板呢?

        2.2 格式

                以下是一个swap模板的实现:

template<typename T>		//这里的typename 是定义模板参数的关键字						
void swap(T& a, T& b)		//typename可用class来替代,但是不可用struct
{
	T tmp = a;
	a = b;
	b = tmp;
}

                再次强调定义模板参数的关键字:只能用typename和class不能使用struct

                 我们这时就可以便捷实现出不同类型swap函数,只需要一个模板即可,如下:

template<typename T>							
void Swap(T& a, T& b)		
{
	T tmp = a;
	a = b;
	b = tmp;
}


int main()
{
	int a = 1, b = 2;
	char c = 3, d = 4;
	double e = 5.0, f = 6.0;
	Swap(a, b);
	Swap(c, d);
	Swap(e, f);
	return 0;
}

                这里说一点:这里的swap的首字母一定要大写,否则编译不通过。原因是和库里面的构成重载,编译器无法知道调用哪个。

                这时,读者可能有这样的疑惑:这三个swap函数一样吗?是同一块地址的还是不同地址的?为了解决这个问题,大家想调试可以实现吗?大概率不可以,为啥?因为我们只搞了函数模板,编译器于情于理都会走模板,大家可以去试一试来验证一下。那么,我们有什么办法来验证呢?答案是汇编。

                我们可以看到,虽然他们表面都一样,但是因为调用的地址不同,所以,可以得出结论:三个函数不同。

        2.3 生成原理 

               关于函数的生成原理,我们可以这样想:模板就好比是设计图,根据生产生活的需要,从而搞出不同的东西。

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

 

         2.4 实例化

                用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化

                2.4.1  隐式实例化

                        隐式实例化就是叫函数自己去推到类型,如下:

template <class T>
T Add(T& a, T& b)
{
	return a + b;
}

int main()
{
	int a = 1, b = 2;
	cout << Add(a, b) << endl;
	double c = 3.0, d = 4.0;
	cout << Add(c, d) << endl;
	return 0;
}

                        如果我们要实现以下的函数调用该如何呢?

Add(a, c);

                        这里提供两种解决办法:1、强转 2 、显式实例化。这里咱们来解释显式实例化。

                2.4.2 显式实例化

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

Add<int>(a, c);				//显式实例化

        2.5 匹配原则

                函数模板的匹配遵循以下原则:

                        1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数

                        2. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板

                        3. 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换

                总而言之记住一句话:编译器也和各位一样,喜欢吃现成,即可。 

三、类模板

                类模板基本与函数模板类似,这里简单说一下定义格式和实例化即可:

                3.1 定义格式

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

                因此,我们对于顺序表,可以写出以下模板:

// 动态顺序表
// 注意:Vector不是具体的类,是编译器根据被实例化的类型生成具体类的模具
template<class T>
class Vector
{
public:
	Vector(size_t capacity = 10)
		:_a(new T[capacity])
		,_size(0)
		,_capacity(capacity)
	{}
	~Vector();
	// ........
private:
	T* _a;
	size_t _capacity;
	size_t _size;
};
// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>
Vector<T>::~Vector()
{
	if (_pData)
		delete[] _pData;
	_size = _capacity = 0;
}

        3.2 实例化

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

// Vector类名,Vector<int>才是类型
Vector<int> s1;
Vector<double> s2;

完!

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

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

相关文章

利用ZXing.Net Bindings for EmguCV识别条形码及绘制条形码边框17(C#)

上一篇博文&#xff1a;绘制条形码的效果不是很好&#xff1a;利用Emgucv绘制条形码边框16(C#)-CSDN博客 测试环境&#xff1a; win11 64位操作系统 visual studio 2022 ZXing.Net.Bindings.EmguCV 0.16.4 测试步骤如下&#xff1a; 1 新建.net framework 4.8的控制台项目…

正确利用AI工具,你的facebook广告效果将翻倍

如今投放facebook广告&#xff0c;你面临的对手已经不再是广告投手&#xff0c;而是AI&#xff0c;如果你的广告效果一直无法提升&#xff0c;不妨试着借助一下AI的力量&#xff0c;今天这篇文章就教你怎样才能让AI发挥它的最大价值&#xff0c;帮助我们的facebook广告效果提升…

STM32驱动SG90舵机完成控制

一、前言 SG90舵机的工作原理主要是基于PWM&#xff08;脉冲宽度调制&#xff09;信号来控制。 SG90舵机内部有一个基准电压&#xff0c;微处理器产生的PWM信号通过信号线进入舵机&#xff0c;产生直流偏置电压&#xff0c;与舵机内部的基准电压做比较获得电压差输出。电压差的…

精品在线试题库系统

TOC springboot108精品在线试题库系统 绪论** 1.1 研究背景 现在大家正处于互联网加的时代&#xff0c;这个时代它就是一个信息内容无比丰富&#xff0c;信息处理与管理变得越加高效的网络化的时代&#xff0c;这个时代让大家的生活不仅变得更加地便利化&#xff0c;也让时…

Carry你飞驰:VELO Prevail TT坐垫,不是超人,也能飞!

确认过黑丝腿&#xff0c;是很爱骑的人&#xff01;以前脚踩二八大杠&#xff0c;就能赚足出街回头率&#xff0c;现在的打工牛马是坚持早c晚c&#xff0c;晨骑夜骑解压续命。夏日的阳光炙烤着大地&#xff0c;空气中弥漫着滚滚热浪&#xff0c;对于每一位热爱骑行的骑士来说&a…

WindowsAPI 查阅笔记:网络通信

客户端&#xff1a; 记得在编译的时候加上这个 -lwsock32 -lws2_32。 不然会报错 undefined reference to __imp_WSAStartup‘。 注意&#xff1a;如果端口在此之前被占了&#xff0c;则不会发生预期的结果 服务端&#xff0c;得到连接后创建线程&#xff0c;执行处理函数。…

你真的了解电子标签的潜力吗?3秒快刷颠覆你的想象

随着ESL电子标签在零售领域的大范围应用&#xff0c;其方便快捷更改显示内容的功能也逐渐拓展到仓储显示领域。但是仓储作业过程中货品出入库频繁&#xff0c;常规电子标签在实际使用过程中存在刷新速度偏长&#xff0c;无法充分满足仓储出入库数据更新的需求。因此&#xff0c…

阿里云智能大数据演进

本文根据7月24日飞天发布时刻产品发布会、7月5日DataFunCon2024北京站&#xff1a;大数据大模型.双核时代实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a;徐晟 阿里云研究员/计算平台产品负责人 主要内容&#xff1a; Overview - 阿里云大数据 AI 产品…

秋招突击——面经整理——有塔游戏提前批

文章目录 引言正文一面说一下堆排序 二面有了解过游戏后端应该是干什么的吗&#xff1f;博客是从什么时候开始写的&#xff1f;平常在哪里做题&#xff1f;做了多少题&#xff1f;给你二维矩阵&#xff0c;零代表可以走&#xff0c;一代表不可以走&#xff0c;从起点到终点&…

Java:文件IO

JavaEE16 一、文件系统操作 在java标准库中&#xff0c;实现了File类&#xff0c;其中提供了文件操作的方法&#xff01; 1、构造方法&#xff1a; 方法名说明 File(File parent , String child) 根据父目录孩子文件路径&#xff0c;创建一个新的File 实例File( String path…

dockers 阿里云镜像失效后如何配置,可视化操作

Windows 环境 Client:Version: 24.0.6Context: defaultDebug Mode: false方法一 docker-desktop 配置方式 {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,…

【echarts】甘特图

const milestones [{ progress: 100, milestoneName: 阶段一, startDate: 2020-12-23, endDate: 2021-01-30 },{ progress: 100, milestoneName: 阶段二, startDate: 2021-01-15, endDate: 2021-03-15 },{ progress: 100, milestoneName: 阶段三, startDate: 2021-03-10, endD…

ubuntu 24.04执行apt-get update报错处理

文章目录 一、apt-get update报错内容二、解决启动失败的服务推荐阅读 今天在做Ubuntu 24.04更新时&#xff0c;突然跳出两个报错&#xff0c;这在之前还从未遇到过&#xff0c;处理过程记录和分享一下&#xff1a; 一、apt-get update报错内容 报错截图参考如下&#xff1a; …

现货黄金美盘开盘时间是什么呢

现货黄金的开盘时间会因为地区和平台而有所差异&#xff0c;一般来说&#xff0c;香港的平台在北京时间周一早间7点左右会开盘&#xff0c;并一直持续周六凌晨才收盘&#xff0c;周六和周日是市场的休市时间&#xff0c;期间交易平台一般会关闭&#xff0c;无法进行交易&#x…

一文读懂什么是进销存!进销存有何价值作用?

企业在运营过程中&#xff0c;常常会遇到诸如库存不准确、采购计划混乱、销售数据跟踪困难等问题&#xff0c;这些问题不仅影响了企业的日常运营&#xff0c;还可能导致客户满意度下降、利润受损。而一个合适的进销存系统&#xff0c;就像是一把钥匙&#xff0c;可以帮助企业打…

MySQL基础练习题34-游戏玩法分析4

目录 题目 准备数据 分析数据 总结 题目 报告在首次登录的第二天再次登录的玩家的 比率&#xff0c;四舍五入到小数点后两位。换句话说&#xff0c;你需要计算从首次登录日期开始至少连续两天登录的玩家的数量&#xff0c;然后除以玩家总数。 准备数据 ## 创建库 create…

为什么要学医疗器械维修?

在当今高速发展的医疗领域&#xff0c;医疗器械维修已成为一个极具吸引力和潜力的职业选择。那么&#xff0c;为什么要学习医疗器械维修呢&#xff1f; 一、稳定且持续增长的需求 随着医疗技术的不断进步&#xff0c;医疗器械的种类和数量日益增多。从常见的 X 光机、CT 扫描仪…

新专利:温室土壤温湿度预测模型构建方法和程序产品

&#xff08; 于景鑫 国家农业信息化工程技术研究中心&#xff09;在现代设施农业生产中&#xff0c;温室微环境的精准调控是提高作物产量和品质的关键。然而&#xff0c;由于温室内外环境因素的复杂多变&#xff0c;尤其是土壤温湿度的非线性、非平稳特性&#xff0c;传统的预…

【vue3|第23期】Vite + Vue3: 深入理解public和assets文件夹的作用与使用

日期&#xff1a;2024年8月14日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

如果让你消息队列,该如何设计?说一下你的思路

在当今的分布式系统中&#xff0c;消息队列是一个不可或缺的组件&#xff0c;它在系统解耦、流量削峰、异步处理等方面发挥着重要作用。 如果我要设计一个消息队列&#xff0c;我会从以下几个关键点出发呢&#xff1f; 让我们来探讨一下如何设计一个消息队列的架构。 实现内存…