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

文章目录

  • 泛型编程
  • 模板
    • 函数模板
    • 概念
    • 原理
    • 函数模板的实例化
    • 类模板

泛型编程

我们在实现交换函数的时候,只能实现一个数据类型的交换函数,想要在C++中完成对应类型数据的交换一种方法是使用函数重载,就像下面这样

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

这样写就显得我们不太聪明的样子,这样写的缺点是:重载的函数仅仅是类型不同,代码复用率较低,只要有新类型出现时,就需要用户自己增加对应的函数。代码的可维护性比较低,一个出错可能所有的重载出错。
针对这些问题,C++中提供了模板的语法

模板

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。后面我们将会大量运用泛型编程。
模板可以分为函数模板和类模板

函数模板

我们来看一下这个代码:

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

上面的代码运用了函数模板的概念,template是C++中提供函数模板参数的一个关键字,上面就是一个交换函数的函数模板,该函数可以适应很多类型的数据交换。

概念

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,更具实参类型产生函数的特定类型版本。
格式:template <typename T1,typename T2,……typename Tn>
返回值类型 函数名(参数列表) {}
注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)。

原理

函数模板只是一个模板,它本身不是函数,是编译器使用方式产生特定具体类型函数的模具。所以其实模板就是将本来我们做的重复的事情交给了编译器。
在编译阶段,编译器需要根据传入的实参类型来推演生成对应类型的函数。
在这里插入图片描述

函数模板的实例化

template <typename T>

T Add(const T& left, const T& right)
{
	return left + right;
}

int  main()
{
	int a1 = 1, a2 = 1;
	double d1 = 1.1, d2 = 1.2;
	Add(a1, a2);
	Add(d1, d2);
	//a1和d1不是相同类型的数据,编译器在推演实际的参数是什么类型的时候,
	//会发生二义性的问题,也就是说函数模板参数只有一个编译器不知道是int还是double
	
	//Add(a1, d1);

	//我们可以这样处理
	//这时候我们需要强制类型转换。但是这里还有一个问题,强制类型转换会产生临时变量
	//编译器把这个临时变量传给函数的时候,函数的参数列表必须有const修饰,这是由于
	//临时变量具有常性,如果不加const就会造成权限放大的问题,这时候加上const就是权限平移
	//不会出错
	//1.用户强制转换,2.使用显式实例化(在<>中指定模板参数的实际类型)
	Add(a1, (int)d1);
	Add<int>(a2, d2);
}

也可以这样写,模板参数设置为两个

//通用加法函数
//这样写就不会发生两个类型不同,编译器不知道实例化成哪个的问题了
//但是这样会使精确度下降
template <typename T1,typename T2>
T1 Add(T1& left, T2& right)
{
	return left + right;
}

int main()
{
	int a = 1;
	double b = 1.1;
	cout << Add(a, b) << endl;
}

类模板

定义格式:

template<class T1,class T2,……,class Tn>
class 类模板名
{
	//成员函数
}

实现一个模板栈

template <typename T1>
//模板类
class Stack
{
public:
	Stack(int capacity = 3)
	{
		_array = new T1[capacity];
		_capacity = capacity;
		_top = 0;
	}
	void CheckCapacity()
	{
		if (_top == _capacity)
		{
			T1* temp = (T1*)realloc(_array, sizeof(T1) * _capacity * 2);
			if(NULL == temp)
			{
				perror("realloc failed!\n");
				return;
			}
			_array = temp;
			_capacity *= 2;
			cout << "扩容成功!" << endl;
		}
	}
	void PushStack(T1 x)
	{
		CheckCapacity();
		_array[_top] = x;
		_top++;
	}
	void PopStack()
	{
		if (_top > 0)
		{
			_top--;
		}
		else
		{
			cout << "退栈失败,栈已为空!" << endl;
			return;
		}
	}
	bool EmptyStack()
	{
		return _top == 0;
	}

	T1 StackTop()
	{
		return _array[_top - 1];
	}

	~Stack()
	{
		delete[] _array;
		_array = NULL;
		_capacity = _top = 0;
	}
private:
	T1* _array;
	int _capacity;
	int _top;
};
int main()
{
	Stack<int> s1;
	s1.PushStack(1);
	s1.PushStack(2);
	s1.PushStack(3);
	s1.PushStack(4);
	s1.PushStack(5);
	s1.PushStack(6);
	s1.PushStack(7);
	while (!s1.EmptyStack())
	{
		cout << s1.StackTop() << endl;
		s1.PopStack();
	}
	/*Stack<double> s2;
	Stack<short> s3;*/
	return 0;
}

需要注意:Stack 为类名,Stack<int> 才是类型
在类外定义函数时应该这么写
Stack<T> :: Stack() //在类外定义构造函数

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开发一个RISC-V上的操作系统(五)—— 协作式多任务

目录 往期文章传送门 一、什么是多任务 二、代码实现 三、测试 往期文章传送门 开发一个RISC-V上的操作系统&#xff08;一&#xff09;—— 环境搭建_riscv开发环境_Patarw_Li的博客-CSDN博客 开发一个RISC-V上的操作系统&#xff08;二&#xff09;—— 系统引导程序&a…

【C++】类和对象(下)

1、初始化列表 初始化列表&#xff1a;以一个冒号开始&#xff0c;接着是一个以逗号分隔的数据成员列表&#xff0c;每个"成员变量"后面跟一个放在括号中的初始值或表达式。 class Date { public:Date(int year, int month, int day): _year(year), _month(month), _…

OpenLayers实战进阶专栏目录,OpenLayers实战案例,OpenLayers6实战教程

前言 本篇作为OpenLayers实战进阶教程的目录&#xff0c;用于整理汇总专栏所有文章&#xff0c;方便查找。 OpenLayers是前端最流行的JS二维地图引擎之一。 反馈建议 OpenLayers系列-交流专区&#xff0c;建议和问题反馈 Openlayers实战进阶 Openlayers实战&#xff0c;O…

全志F1C200S嵌入式驱动开发(lcd屏幕驱动)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 lcd RGB屏幕作为比较经济、实用的显示工具,在实际场景中使用较多。它的信号来说,一般也比较简单,除了常规的数据信号,剩下来就是行同步、场同步、数据使能和时钟信号了。数据信…

Pytorch深度学习-----神经网络之池化层用法详解及其最大池化的使用

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用&#xff08;ToTensor&#xff0c;Normalize&#xff0c;Resize &#xff0c;Co…

Python批量将Excel内指定列的数据向上移动一行

本文介绍基于Python语言&#xff0c;针对一个文件夹下大量的Excel表格文件&#xff0c;对其中的每一个文件加以操作——将其中指定的若干列的数据部分都向上移动一行&#xff0c;并将所有操作完毕的Excel表格文件中的数据加以合并&#xff0c;生成一个新的Excel文件的方法。 首…

虚拟机(VMware)安装Linux(Ubuntu)安装教程

清华大学开源网站镜像站网址&#xff1a;清华大学开源软件镜像站 | Tsinghua Open Source Mirror 进入之后在搜索框中搜索“ubuntu” 直接点击箭头所指的蓝色字体“ubuntu-20.04.1-desktop-amd64.iso”即可下载

一起学算法(位运算篇)

1.位运算 1.二进制数值表示 在计算机中&#xff0c;我们可以用单纯的0和1来表示数字&#xff0c;一般不产生歧义&#xff0c;我们会在数字的右下角写上它的进制&#xff0c;例如&#xff1a;1010&#xff08;10&#xff09;其表示的是1010&#xff0c;1010&#xff08;2&#…

Windows下安装HBase

Windows下安装HBase 一、HBase简介二、HBase下载安装包三、环境准备3.1、 JDK的安装3.2、 Hadoop的安装 四、HBase安装4.1、压缩包解压为文件夹4.2、配置环境变量4.3、%HBASE_HOME%目录下新建临时文件夹4.4、修改配置文件 hbase-env.cmd4.4.1、配置JAVA环境4.4.2、set HBASE_MA…

【css】背景图片附着

属性&#xff1a;background-attachment 属性指定背景图像是应该滚动还是固定的&#xff08;不会随页面的其余部分一起滚动&#xff09;。 background-attachment: fixed&#xff1a;为固定&#xff1b; background-attachment: scroll为滚动 代码&#xff1a; <!DOCTYPE h…

【1.4】Java微服务:服务注册和调用(Eureka和Ribbon实现)

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。 &#x1f34e;个人主页&#xff1a;Meteors.的博客 &#x1f49e;当前专栏&#xff1a; 微服务 ✨特色专栏&#xff1a; 知识分享 &#x…

企业数据,大语言模型和矢量数据库

随着ChatGPT的推出&#xff0c;通用人工智能的时代缓缓拉开序幕。我们第一次看到市场在追求人工智能开发者&#xff0c;而不是以往的开发者寻找市场。每一个企业都有大量的数据&#xff0c;私有的用户数据&#xff0c;自己积累的行业数据&#xff0c;产品数据&#xff0c;生产线…

【Linux进程篇】进程概念(1)

【Linux进程篇】进程概念&#xff08;1&#xff09; 目录 【Linux进程篇】进程概念&#xff08;1&#xff09;进程基本概念描述进程-PCBtask_struct-PCB的一种task_ struct内容分类 组织进程查看进程通过系统调用获取进程标示符通过系统调用创建进程——fork初识 作者&#xff…

2023软件设计师中级备考经验分享(文中有资料链接分享)

先摊结论吧&#xff0c;软考中级设计师备考只是备考半个月&#xff08;期间还摆烂了几天&#xff09;&#xff0c;然而成绩如下&#xff1a; 我自己都没想到会这么好的成绩。。。 上午题&#xff1a;推荐把软考通APP里的历年真题刷3-4遍&#xff0c;直接刷真题&#xff0c;然后…

分享一些精选的开源框架与代码!

今天主要是收集并精选了一些自己所了解和学习过的优秀的嵌入式开源框架代码和项目&#xff0c;不太了解的就不推荐给大家了&#xff0c;因为开源的东西实在是太多了&#xff0c;鱼龙混杂&#xff0c;所以取其精华去其糟粕是迫在眉睫的大事~ 当然也不要总是沉浸在开源的东西之中…

光伏、储能一体化监控及运维解决方案

前言 今年以来&#xff0c;在政策利好推动下光伏、风力发电、电化学储能及抽水蓄能等新能源行业发展迅速&#xff0c;装机容量均大幅度增长&#xff0c;新能源发电已经成为新型电力系统重要的组成部分&#xff0c;同时这也导致新型电力系统比传统的电力系统更为复杂&#xff0…

基于多任务学习卷积神经网络的皮肤损伤联合分割与分类

文章目录 Joint segmentation and classification of skin lesions via a multi-task learning convolutional neural network摘要本文方法实验结果 Joint segmentation and classification of skin lesions via a multi-task learning convolutional neural network 摘要 在…

idea 里 controller service impl mapper xml 切换跳转快捷键

首先在controller层&#xff0c;对着接口点方法的方法上按着ctrl和鼠标左键&#xff0c;你会进入service层。 对着方法ctrlaltb不按鼠标&#xff0c;你会进入impl层。service层的方法上按ctrl和鼠标左键会回到controller&#xff0c;ctrlaltb不按鼠标也会进入到impl层,impl上的…

vue echart3个饼图

概览&#xff1a;根据UI设计需要做3个饼图且之间有关联&#xff0c;并且处理后端返回的数据。 参考链接&#xff1a; echart 官网的一个案例&#xff0c;3个饼图 实现思路&#xff1a; 根据案例&#xff0c;把数据处理成对应的。 参考代码&#xff1a; 1.处理后端数据&am…

谐音标注外语发音的学习方式,早该终结了!

语言学习的热潮席卷全国&#xff0c;在多数80、90后记忆里尤为深刻&#xff0c;部分对外语过敏的同学&#xff0c;就像溺水的鱼&#xff0c;使劲扑棱也无济于事&#xff0c;难受但是死不了&#xff0c;在懵懂的年纪就被“摧残”了整个青春。 记忆中遇到记不住读音的单词&#x…
最新文章