C++详解->函数模板+类模版

news2024/12/24 2:47:23

在这里插入图片描述

文章目录

  • 前言
    • 1、反泛型编程
    • 2、函数模板
      • (1)、函数模板概念
      • (2)、函数模板定义格式
      • (3)、函数模板实例化
      • (4)函数模板参数匹配原则
    • 3、类模版
      • (1)类模板实例化
      • (2)类模板实现Stack(压/出栈函数)

前言

此篇主要描述函数模板的概念、格式以及实例化等;

1、反泛型编程

有学Java语言的同学,会听过里面的泛型。简单说就是给一个函数框架,可以实现调用不同类型的函数。是代码复用的手段。然而模版就是泛型编程的基础。
接下来看一下函数模板:

2、函数模板

此处先用一个例子引入:
在这里插入图片描述
改写后:
在这里插入图片描述
从上面可以看出模板的便利之处,可以减少代码量,提高效率,接下来看一看模板的概念和格式定义🚗🚗🚗🚗

(1)、函数模板概念

①概念:函数模板是一种允许程序员编写一个可以处理多种数据类型的函数的方法。‌它通过使用虚拟类型参数来代替具体的类型,‌使得函数可以处理不同类型的数据,‌从而实现了代码的复用和灵活性。

(2)、函数模板定义格式

template<typename T1, typename T2,…,typename Tn>这是模板的关键字。
注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替
class)

template<class T>
//template<typename T>
void Swap(T& x, T& y)
{
	T tmp = x;
	x = y;
	y = tmp;
}

(3)、函数模板实例化

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

隐式实例化和显式实例化。

  1. 隐式实例化:
template<class T>
T Add(const T& a,const T& b)
{
	return a + b;
}
int main()
{
	int a1 = 10, a2 = 20;
	double b1 = 2.1, b2 = 3.0;
	cout << Add(a1, a2) << "\n";
	cout << Add(b1, b2) << "\n";
	//出现两种类型的时候,时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化
	cout << Add(a1, (int)b1) << "\n";
	return 0;
}
  1. 显示实例化:在调用函数名后的<>中指定模板参数的实际类型
	//显示实例化
	cout << Add<int>(a1, a2) << "\n";

(4)函数模板参数匹配原则

①非模板函数可以和一个同名的模板函数同时存在,并且模板函数可以被实例化为非模板函数。
②模板函数不允许自动类型转换,但普通函数可以进行自动类型转换。
③非模板函数和模板函数同名的时候,在其他参数以及返回值都相同的时候,会优先调用非模板函数,不会通过模板函数生成一个实例。但是模板函数中有更匹配的函数,那么会选择模板函数。

int Add(int a, int b)
{
	return a + b;
}

template<class T>
T Add(const T& a,const T& b)
{
	return a + b;
}
int main()
{
	int a1 = 10, a2 = 20;
	double b1 = 2.1, b2 = 3.0;
	//cout << Add(a1, a2) << "\n";
	//cout << Add(b1, b2) << "\n";
	//cout << Add(a1, (int)b1) << "\n";
	显示实例化
	//cout << Add<int>(a1, a2) << "\n";
	cout<<Add(1, 2)<<"\n"; // 与非函数模板类型完全匹配,不需要函数模板实例化
	cout << Add(1, 2.0) << endl;//非模板函数,会自动类型转换
	return 0;
}

3、类模版

函数模板是在函数前面加template<class T,……>,因此类模版格式类似的。

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

(1)类模板实例化

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

// Stack是类名,Stack<int>才是类型
Stack<int> st1; // int
Stack<double> st2; // double

(2)类模板实现Stack(压/出栈函数)

#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;


template<typename T>
class Stack
{
public:
	Stack(size_t capacity = 4)
	{
		_array = new T[capacity];
		_capacity = capacity;
		_size = 0;
	}

	void Push(const T& data);
	T GetTop();
	void Pop();

	~Stack()
	{
		delete[] _array;
		_array = nullptr;
		_size = _capacity = 0;
	}

private:
	T* _array;
	size_t _capacity;
	size_t _size;
};

template<typename T>
void Stack<T>::Push(const T& data)
{
	if (_size == _capacity)
	{
		//开新空间
		T* tmp = new T[_capacity * 2];
		//拷贝新空间
		memcpy(tmp, _array, sizeof(T) * _size);
		//释放原空间
		delete[] _array;
		//指向新空间
		_array = tmp;
		_capacity *= 2;
	}
	_array[_size++] = data;
}

template<typename T>
T Stack<T>::GetTop()
{
	if (_size == 0)
	{
		return -1;
	}
	return  _array[_size-1];
}

template<typename T>
void Stack<T>::Pop()
{
	if (_size == 0)
	{
		return;
	}
	_size--;
}

int main()
{
	Stack<int> st1;
	st1.Push(1);
	st1.Push(2);
	st1.Push(3);
	st1.Push(4);
	st1.Push(5);
	cout << st1.GetTop() << "\n";
	st1.Pop();
	cout << st1.GetTop() << "\n";

	return 0;
}


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

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

相关文章

AppInventor做的APP支持安卓14吗?

目前MIT最新版本也是Android13&#xff0c;我们与mit同步更新。如果官方支持14我们会第一时间跟进。不过&#xff0c;根据用户反馈&#xff0c;蓝牙相关的好像不兼容~ 有关安卓 14 的补充&#xff1a;根据反馈&#xff0c;是支持14的&#xff0c;不过需要手动开启蓝牙权限 …

【HarmonyOS】鸿蒙应用实现截屏

【HarmonyOS】鸿蒙应用实现截屏 组件截屏 通过componentSnapshot的get函数&#xff0c;将需要截图的组件设置id传进去即可。 import { componentSnapshot } from kit.ArkUI; import { image } from kit.ImageKit;/*** 截图*/ Entry Component Preview struct SnapShotPage {S…

16.2 商品秒杀场景处理

16.2 商品秒杀场景处理 1. 秒杀业务流程解析2. 限速手段************************************************************************ 1. 秒杀业务流程解析 VIP秒杀 通过前端验证码限速 2. 限速手段 ********************************************************************…

VMware虚拟机Ubuntu20.04的安装和配置

Ubuntu20.04和VMware安装 Windows系统下Ubuntu20.04镜像源下载&#xff1a;Ubuntu20.04系统下载 VMware下载 百度网盘链接&#xff1a;https://pan.baidu.com/s/1Fp6GYPDFksEGCNZ0JikfAg 提取码: 8jhs 虚拟机配置Ubuntu 打开VMware点击创建新的虚拟机 - > 典型 - …

golang Goroutine协程和Channel管道

同步/并发/并行概念 在计算机科学和软件开发中&#xff0c;同步、并发和并行是三个重要的概念&#xff0c;它们描述了程序执行的不同方式 同步 (Synchronization) 定义&#xff1a;同步指的是一种操作或任务在进行时&#xff0c;调用者需要等待该操作或任务完成才能继续执行…

SD-WAN组网技术的九大应用场景

SD-WAN组网&#xff0c;即软件定义广域网&#xff0c;为企业提供了高效、灵活且安全的网络连接。这种新兴网络技术不仅改变了传统WAN的组网方式&#xff0c;更带来了诸多应用场景和解决方案。接下来&#xff0c;我们将深入探讨SD-WAN的主要应用场景。 1、首先&#xff0c;SD-WA…

[Bugku] MISC-CTF靶场系列系列详解⑤!!!

平台为“山东安信安全技术有限公司”自研CTF/AWD一体化平台&#xff0c;部分赛题采用动态FLAG形式&#xff0c;避免直接抄袭答案。 平台有题库、赛事预告、工具库、Writeup库等模块。 ------------------------------ 社工-进阶收集 开启环境&#xff1a; --------- 下载附件…

医院AR导航系统的实现:科技助力智慧医疗构建

在快节奏的现代医疗环境中&#xff0c;患者与医护人员对高效、便捷的院内导航需求日益增长。随着科技的飞速发展&#xff0c;传统的纸质地图已难以满足复杂多变的医疗空间需求。在此背景下&#xff0c;集成AR&#xff08;增强现实&#xff09;技术的院内导航系统应运而生&#…

3.表的操作

目录 创建表 创建表案例&#xff1a; 查看表结构 修改表 1.增加新列 2.修改列的属性 3.删除列 4.修改表名 5.修改列 删除表 创建表 语法&#xff1a; CREATE TABLE [IF NOT EXISTS] table_name(field1 datatype1 [COMMENT 注释信息],field2 datatype2 [COMMENT 注释…

华清day7 24-8-5

文章目录 使用有名管道实现&#xff0c;一个进程用于给另一个进程发消息&#xff0c;另一个进程收到消息后&#xff0c;展示到终端上&#xff0c;并且将消息保存到文件上一份使用有名管道实现两个进程间相互通信 使用有名管道实现&#xff0c;一个进程用于给另一个进程发消息&a…

WPF学习(1)-Grid控件(网格布局)

Grid控件其实是一个窗体的默认控件&#xff0c;我们创建一个WPF应用程序后&#xff0c;其主窗体里面会有一个Grid控件。 Grid有两个非常关键的属性ColumnDefinitions和RowDefinitions&#xff0c;分别表示列的数量集合和行的数量集合。 ColumnDefinitions集合中的元素类型是…

终于有人把华为认证全部说清楚了

在信息技术领域&#xff0c;华为认证好比一座金字招牌&#xff0c;吸引着无数技术专业人士的青睐。 市场上关于华为认证的声音纷繁复杂&#xff0c;存在不少争议&#xff0c;让人难以辨别真伪。 今天就来好好讲讲华为认证&#xff0c;从头到尾都帮你盘盘清楚。 01 华为认证是…

论文辅导 | 基于二次分解和BO-BiLSTM组合模型采煤工作面瓦斯涌出量预测方法研究

辅导文章 模型描述 结合变分模态分解&#xff08;VMD&#xff09;、自适应噪声完备经验模态分解&#xff08;CEEMDAN&#xff09;、贝叶斯优化算法&#xff08;BO&#xff09;和双向长短期记忆神经网络&#xff08;BiLSTM&#xff09;这4种时间序列处理方法&#xff0c;建立了…

EKMA曲线及大气O3来源解析实践技术

目前&#xff0c;大气臭氧污染成为我国“十四五”期间亟待解决的环境问题。臭氧污染不仅对气候有重要影响&#xff0c;而且对人体健康、植物生长均有严重损害。为了高效、精准地治理区域大气臭氧污染&#xff0c;首先需要了解导致臭氧生成的主要前体物。因此&#xff0c;EKMA曲…

图的DFS

LeetCode2368 受限条件下可到达节点的数目 class Solution { public:int dfs(vector<vector<int>>& g,int x,int fa){int sum1;for(int y:g[x]){if(y!fa) sumdfs(g,y,x);}return sum;}int reachableNodes(int n, vector<vector<int>>& edges, …

C#—串口和网口之间的通信详解

C#—串口和网口之间的通信 串口转网口、网口转串口&#xff0c;就是将网口发送来的数据包发送给串口设备&#xff0c;将串口设备返回的数据转发给网口客户端。 在C#中&#xff0c;将串口数据转换为网络数据并发送到网络&#xff0c;通常涉及以下步骤&#xff1a; 1. 创建一个…

C# Unity 面向对象补全计划 七大原则 之 里氏替换(LSP) 难度:☆☆☆ 总结:子类可以当父类用,牛马是马,骡马也是马

本文仅作学习笔记与交流&#xff0c;不作任何商业用途&#xff0c;作者能力有限&#xff0c;如有不足还请斧正 本系列作为七大原则和设计模式的进阶知识&#xff0c;看不懂没关系 请看专栏&#xff1a;http://t.csdnimg.cn/mIitr&#xff0c;尤其是关于继承的两篇文章&#xff…

相机无须标定,使用基础矩阵F实现多相机内参自标定

Abstract 从给定的基本矩阵中进行两个摄像头的自我校准问题是几何计算机视觉中的基本问题之一。在已知主点和正方形像素的假设下&#xff0c;Bougnoux公式提供了一种计算两个未知焦距的方法。然而&#xff0c;在许多实际情况下&#xff0c;由于常见的奇异性&#xff0c;公式会…

xshell无法连接Ubuntu20.4

在之前红帽版本里&#xff0c;直接下了就可以用xshell直接连接&#xff0c;但是Ubuntu20.4不能直接连接&#xff0c;我开始以为是密码错了&#xff0c;但是我想了想vscode连接不需要密码&#xff0c;一样连接不上&#xff0c;我就在网上找了很多方法&#xff0c;最后终于连接上…

总线学习4--UART

想来串口通信是我第一次接触嵌入式就知道的&#xff0c;一直调试也是用串口线&#xff0c;但是里面的原理还真不清楚。这次难得把环境弄出来了&#xff0c;就顺便学学。 一 环境搭建 还是老规矩&#xff0c;废话不多说&#xff0c;干就完事。 这次用的树莓派zero小板&#x…