【C++】模板(初级)

C++基础——模板 模板是一种较为通用的模具,不能单独使用C++除了面向对象编程之外,还有一种是泛型编程,使用的就是模板C++中提供了两种模板:函数模板,类模板。 阅读详情

目录

一、 泛型编程

二、 函数模板

2.1 函数模板概念

2.2 函数模板格式

2.3 函数模板的原理

2.4 函数模板的实例化

2.5模板参数的匹配原则

三、 类模板

3.1 引入

3.2 类模板实现Stack

一、 泛型编程

在以下这种场景中便会出现泛型编程(实现一个通用的交换函数):

在C++中有函数重载功能,如果我们要实现这以上三组数据的交换,明显要实现 3 组 swap 函数,

使用函数重载虽然可以实现,但是有以下几个不好的地方:

  1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数
  2. 代码的可维护性低i。一个出错可能所有的重载均出错。

这样重复而赘余的代码是很不合理的,所以C++引入了模板,这泛型编程。

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

二、 函数模板

2.1 函数模板概念

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


2.2 函数模板格式

为了实现上面 swap 函数,所以我们可以定义一以下函数模板。

 注意: typename 是用来定义模板参数的关键字,也可以使用 class (但不能使用 struct 代替 class)


2.3 函数模板的原理

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

在编译器编译阶段,对于模板函数的的使用,编译器需要根据传入的实参类型来推演生成的对应类型的函数以供调用。

比如:当用 double 类型使用函数模板时,编译器通过对实参的推演,将 T 确定为 double 类型,然后产生一份专门处理 double 类型的代码,对于字符类型也是如此。


2.4 函数模板的实例化

用不同类型的参数使用函数模板时,成为函数模板的实例化。

模板参数实例化分为:

  • 隐式实例化:让编译器根据实参推演模板参数的实际类型。
  • 显示实例化:在函数名后的 < >中指定模板那参数的实际类型。

隐式实例化:

 现在引申出一个问题:如果我们传入的参数类型不相同,那应该怎么办呢?

例如,我使用上面的 Add 函数将一个 int 型数据和 double 数据相加,那会产生什么结果呢?

如果出现了上面这种情况,编译器就会报错,就好比你的左手和右手,两个相同的指令,编译器就无法分辨了。

这时,我们就可以使用显示实例化来解决,将类型直接指定为 int 。

 方法一:显示实例化:

方法二:上面这种场景,还可以使用强制类型转换,但是效果相同的。

 方法三: 书写一个使用了两个模板参数的函数。

 使用方法三,就又会引申出一个问题,这样,再调用 Add 函数的时候, 是会调用一个模板的呢,还是两个不同的模板参数的呢?

如果两个类型相同,就会去调用一个模板参数的函数,如果两个参数类型不同,就会调用两个模板参数的模板函数。


2.5模板参数的匹配原则

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

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


三、 类模板

3.1 引入

 以前我们在 C 语言中使用 typedef 模仿泛型编程,但是这种方式远远不能叫做泛型编程。

因为他还是在针对具体的类型来进行的。 例如,我们想让一个栈的数据结构,既能存放 char 型数据,也能存放 int 型数据 ,这时, typedef 就无法解决这样的问题,只能通过书写两套栈来实现刚刚提到的场景。

学习了类模板之后,我们就可以这样来实现栈。 


3.2 类模板实现Stack

template <class T>
class Stack
{
public:
	Stack(int capacity=4)
		:_a(nullptr)
		,_top(0)
		,_capacity(0)
	{
		//防止传入参数中 capacity为0 ,则不扩容直接结束
		if (capacity >0)
		{
			_a = new T[capacity];
			_capacity = capacity;
			_top = 0;
		}
	}

	~Stack()
	{
		delete[] _a;
		_a = nullptr;
		_capacity = _top = 0;
	}

	void CheckCapacity()
	{
		if (_capacity == _top)
		{
			size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
			//这里不做检查,检测的话用 try catch 即可
			T* temp = new T[newcapacity];
			//如果原来数组有数据,将数据拷贝过来
			if (_a)
			{
				memcpy(temp, _a, sizeof(T) * _top);
				delete[] _a;
			}
			_a = temp;
			_capacity = newcapacity;
		}
	}

	void Push(const T& val)
	{
		CheckCapacity();
		_a[_top] = val;
		_top++;
	}

	void Pop()
	{
		assert(_top > 0);
		--_top;
	}

	 T& Top()
	{
		assert(_top > 0);
		return _a[_top-1];
	}
	 bool Empty()
	 {
		 return _top == 0;
	 }
private:
	T* _a;
	size_t _capacity ;
	size_t _top;
};


int main()
{
	Stack<int>st1;
	st1.Push(1);
	st1.Push(2);
	st1.Push(3);
	st1.Push(4);
	st1.Push(5);
	st1.Push(6);

	while (!st1.Empty())
	{
		cout << st1.Top() << endl;
		st1.Pop();
	}
	return 0;
}

深入解析XTEA加密算法的核心机制与优化策略 本文深入解析XTEA加密算法的核心机制与优化策略,详细介绍了XTEA在嵌入式系统和资源受限环境中的优势,包括其高效的加解密速度和低资源消耗。文章还探讨了XTEA的轮函数设计、关键参数优化策略以及实战应用中的性能对比,为开发者提供了安全增强方案和优化技巧。 阅读详情

相关推荐

QMI8658A和QMC5883L传感器校准全攻略:从零偏校准到椭球拟合

本文详细解析了QMI8658A和QMC5883L传感器的校准方法,从零偏校准到椭球拟合,涵盖了9轴运动传感器的核心误差来源及补偿技术。通过实战案例和数学建模,帮助开发者提升传感器精度,适用于无人机、AR/VR等智能硬件应用。

weixin_29189381的博客 157

【C++基础】模板

模板就是建立,大大。

qq_43192337的博客 318

windows局域网文件夹共享

windows局域网共享文件夹,亲测,包括可能出现的一些问题解决

yml15180824993的博客 4万+

C++——模板(超详细的模板解析)

超详细的C++模板知识列表,持续维护。

JAN6055的博客 5万+

CANoe/CANalyzer新手必看:从零配置到报文分析的完整流程(附B站官方教程实操)

本文为CANoe/CANalyzer新手提供从零配置到报文分析的完整流程指南,涵盖硬件连接、工程配置、报文捕获及信号级分析等关键步骤。通过详细的实操案例和B站官方教程,帮助工程师快速掌握汽车电子总线分析工具的核心应用,提升诊断效率与通信系统理解。

y7z8a的博客 771

Ubuntu18.04环境搭建与疑难解析:从零复现YOLO-6D姿态估计算法

本文详细介绍了在Ubuntu18.04环境下从零开始复现YOLO-6D姿态估计算法的完整流程,包括系统配置、Conda环境搭建、PyTorch安装、依赖项管理、源代码获取、数据集准备以及训练验证过程。针对Singleshotpose算法的特殊需求,提供了详细的疑难解析和性能优化技巧,帮助开发者高效完成算法复现和应用部署。

weixin_30369041的博客 452

C++基础之模板详解

C++中模板是泛型编程的基础,是将类型作为参数的一种编程方式。因此可以独立与特定的类型。模板顾名思义就是一个模子,举个不太恰当的栗子:做月饼的模子,样子都是一样的,但是可以做出五仁的、豆沙的、蛋黄的等等各种馅的月饼。 C++中模板的应用主要分为两个场景:函数模板和类模板。下面分别介绍一下,能想到的尽量都写一下。 函数模板 定义方式 template <typename T[,typename Q]> return_type func_name(param_list) { //函数体 } te

itlilyer的博客 607

UNITY3D万人同屏,Dots万人同屏解决方案_类萌宠宠之战

UNITY3D弹幕游戏开发,万人同屏解决方案

6469

(B站黑马C++)模板

记录代码,只用于复习

IT OR 考公? 2883

基于STM32的汽车主门电动窗开关系统设计方案

以下是基于 STM32CubeMX 和 HAL 库的示例代码,可实现基本的功能。

weixin_42300449的博客 994

【测开求职】面试题:数据结构 吐血整理

本篇文章是笔者为准备研究生复试以及校招而写,因此主要针对问答,注重理解,而不在于细节计算。涵盖考研范围内的所有知识内容,读者可以先查看上面的链接走一遍数据结构的整体框架结构。其中,重点难点以及易混淆的知识点,笔者用其他近30篇文章进行了详述,在知识点处贴好了链接,有需要的可以查阅。

vector的博客 7063

CPP初级:模板的运用!

哇去,这篇文章居然讲透了模板?

duanku111的博客 1315

Mstar的Monitor方案OSD 菜单制作(五)——icon绘制

Mstar的Monitor方案(五)————绘制icon

android 系统定制开发那些事 1807

【C++】模板初级

主要介绍了函数模板与类模板

dab112的博客 1453

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

C++ 模板初级

通过模板,我们可以编写更简洁、复用性更高的代码,而编译器会根据具体使用的类型生成对应的函数,不会混淆不同的类型。显式实例化:明确指定类型,适用于需要确定类型或编译器无法正确推断类型的情况。隐式实例化:代码更简洁,适用于编译器能够正确推断类型的情况。非模板函数优先:如果有一个非模板函数的参数类型完全匹配,编译器会优先选择它。模板函数其次:如果没有找到完全匹配的非模板函数,编译器会尝试使用模板函数进行匹配,并实例化一个具体的函数。模板的灵活性。

m0_72625526的博客 861

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C++:模板初级

使用函数重载虽然可以实现,但是有一下几个不好的地方:1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增 加对应的函数2. 代码的可维护性比较低,一个出错可能所有的重载均出错 那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?如果在C++中,也能够存在这样一个模具,通过给这个模具中填充不同材料(类型),来获得不同 材料的铸件(即生成具体类型的代码),那将会节省许多材料。巧的是前人早已将树栽好,我们只 需在此乘凉。

2303_81073778的博客 1345

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

C++:模板(初级)

我们知道再制造月饼或其它食物时,会用到模具可以用来快速制作食品样子,即使食品的材料不一样,但是造出来的样子都是大差不差的。以上代码都是实现了交换的功能,利用了函数重载,但是要交换不同的类型,就要再写一次函数,那实在是太麻烦了,所以引入了模板。以交换功能为主,实现多种类型的交换,也就是:“交换功能”为模板,“交换类型”为材料,我们来提供材料,编译器负责用模板制造。class 类模板名// 类内成员定义public:, _size(0){}

2301_80153885的博客 1408

C++初级_模板

C++初级_模板 1.非类型模板参数 模板参数:类类型形参、非类型形参 类类型形参:出现在模板参数列表中,跟在class或typename之类的参数类型名称 非类型形参:用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当场常量来对待 注: 浮点数、类对象以及字符串是不允许作为非类型模板参数的 非类型的模板参数必须在编译期就能确认结果 #include<iostre...

qq_42627691的博客 227

C++11后的初级模板

2)如果expression是一个函数调用,则var的类型与函数的返回值类型相同(函数不能返回void,但可以返回void *)。3)非约束模板友元:模板类实例化时,如果实例化了n个类,也会实例化n个友元函数,每个实例化的类都拥有n个友元函数。具体化程度高的类优先于具体化程度低的类,具体化的类优先于没有具体化的类。1)非模板友元:友元函数不是模板函数,而是利用模板类参数生成的函数。2)约束模板友元:模板类实例化时,每个实例化的类对应一个友元函数。2)函数模板,参数和返回值是某种的模板类。

喜欢打篮球的普通人 764

C++初级---模板初阶

本文解释函数模板

weixin_63219391的博客 1108

c++初级 之 模板

具体可以参考http://www.cnblogs.com/gw811/archive/2012/10/25/2738929.html 唯一要注意的是,在vs2012环境里,模板代码不能分开编译,模板的声明和实现都放在一个.h文件中,不要分开成.h和.cpp两个文件,否则编译通不过。

zealice的博客 376

C++之初级模板

文章摘要:本文介绍了C++函数重载的局限性及模板的优势。函数重载在类型不同时代码复用率低且维护困难,而模板通过typename/class关键字可自动生成对应类型的函数。函数模板在编译期实例化,无运行时效率损失。文章还探讨了模板与非模板函数的调用优先级,以及类模板的定义与显示实例化方法,包括命名空间中的类模板实现和声明定义分离的处理方式。

2503_92261635的博客 161

C++之内存管理与模板初级

本文介绍了C++内存管理和模板的基础知识。内存管理部分详细讲解了C/C++内存分布,对比了C的malloc/calloc/realloc/free与C++的new/delete操作符在动态内存管理上的区别,指出new/delete会调用构造函数和析构函数。模板部分简述了模板在C++中的重要意义,说明模板是泛型编程的基础,通过函数模板示例展示了编译器如何根据数据类型生成对应的函数。文章还剖析了new/delete的底层实现原理,指出其通过operator new/delete函数最终调用malloc/free

2401_84420653的博客 1311

C++入门(四)之模板初级

C语言为什呢不提供各种数据结构呢? 因为它不支持泛型编程,不支持泛型编程就意味着你写出的一个栈就只能存int

cls的博客 700

cpp的内存管理和模板初级

在c语言中有malloc、realloc、free函数来进行动态内存上的管理,在cpp中产生了new,delete操作符来分配动态内存,为什么会出现new和delete呢,主要是因为cpp是面向对象的语言他需要更加规范的使用。接下来来分析new和malloc的区别。

2301_77312705的博客 187

【C++】-- 初级模板

【C过渡到C++】-- 初级模板 -- 初级模板的详细使用与原理

weixin_64609308的博客 189
上一篇: 【C++】内存管理——new与delete
下一篇: 【C++】STL中 string 的常用接口
Brant_zero2022
博客等级 码龄5年 582粉丝 108原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Brant_zero2022

素材免费分享不求打赏,只求关注

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值