面向对象程序设计(C++)模版初阶

news2024/9/17 7:22:03

1. 函数模版

1.1 函数模版概念 

       函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本,可以类比函数参数,函数模版就是将函数参数替换为特定类型版本


1.2 函数模版格式

template<typename T1,typename T2,.......,typeneme Tn>

其中 typename 可以替换为 class ,但是切记不可以替换为 struct

接下来以一个Swap函数为例(C++库里已经定义好了swap函数,可以直接使用,这里只是做演示)

#include<iostream>
using namespace std;
template <class T>
void Swap(T& x, T& y)
{
	T tmp = x;
	x = y;
	y = tmp;
}

int main()
{
	int x = 1, y = 2;
	double i = 13.14, j = 5.20;
	Swap(x, y);
	Swap(i, j);
	cout << "x = " << x << "\t" << "y = " << y << endl;//x = 2 , y = 1
	cout << "i = " << i << "\t" << "j = " << j << endl;//i = 5.20 , j = 13.14

	return 0;
}


1.3 函数模版原理

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应 类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此


1.4 函数模版实例化

1. 隐式实例化:让编译器根据实参推演模板参数的实际类型

如上面的Swap函数举例就是隐式实例化,是通过实际输入的参数类型进行实例化,较为简单

#include<iostream>
using namespace std;
template <class T>
void Swap(T& x, T& y)
{
	T tmp = x;
	x = y;
	y = tmp;
}

int main()
{
	int x = 1, y = 2;
	double i = 13.14, j = 5.20;
	Swap(x, y);//隐式实例化
	Swap(i, j);//隐式实例化
	cout << "x = " << x << "\t" << "y = " << y << endl;//x = 2 , y = 1
	cout << "i = " << i << "\t" << "j = " << j << endl;//i = 5.20 , j = 13.14

	return 0;
}

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

以Add函数为例,如果输入的参数不是同一类型就需要显示实例化,比如

#include<iostream>
using namespace std;

template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}

int main()
{
	int x = 2;
	double y = 3.14;

	//显示实例化
	cout << Add<int>(x, y) << endl;//5
	cout << Add<double>(x, y) << endl;//5.14

	return 0;
}

当然也可以使用推到实例化以及定义一个新的函数模版来实现不同参数的Add函数

#include<iostream>
using namespace std;

template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}
//新的函数模版
template<class T1,class T2>
T1 Add(const T1& left, const T2& right)
{
	return left + right;
}

int main()
{
	int x = 2;
	double y = 3.14;

	//显示实例化
	cout << Add<int>(x, y) << endl;//5
	cout << Add<double>(x, y) << endl;//5.14

	//推到实例化
	cout << Add(x, (int)y) << endl;
	cout << Add((double)x, y) << endl;

	//新的函数模版
	cout << Add(x, y) << endl;//5

	return 0;
}

1.5 函数模版匹配规则 

1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个       非模板函数,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一        个实例

#include<iostream>
using namespace std;

template<class T>
T Add(const T& x, const T& y)
{
	return x + y;
}

int Add(const int& x, const int& y)
{
	return (x + y) * 10;
}

int main()
{
	int x = 1;
	int y = 2;
	//优先调用非模版函数
	cout << Add(x, y) << endl;//30
	return 0;
}

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


2. 类模版

2.1 类模板的定义格式

template<class T1, class T2, ..., class Tn> 

class 类模板名
{
 // 类内成员定义
};   

接下来以一个 Stack 类为实例

//类模版
template <class T>
class Stack
{
public:
	Stack(int n = 4)
		:_array(new T[n])
		,_size(0)
		,_capacity(n)
	{};
	~Stack() 
	{
		delete[] _array;
		_array = nullptr;
		_capacity = _size = 0;
	};

	void Push(const T& x);
private:
	T* _array;
	size_t _capacity;
	size_t _size;
};
//在类外定义需要注意格式,要重新定义模版,此处的T可以是其他名字,只充当一个代号
template<class T>
void Stack<T>::Push(const T& x)
{
	//首先判断是否需要扩容
	if (_capacity == _size)
	{
		//创建一个新数组,大小是原来数组的两倍,存储原来的数据
		T* tmp = new T[_capacity * 2];
		memcpy(tmp, _array, sizeof(T) * _size);
		delete[] _array;

		_array = tmp;
		_capacity *= 2;
	}
	_array[_size++] = x;
}

int main()
{
	//int 类型的Stack
	Stack<int> st1;
	st1.Push(1);
	st1.Push(1);
	st1.Push(1);

	//double 类型的Stack
	Stack<double> st2;
	st2.Push(1.1);
	st2.Push(1.1);
	st2.Push(1.1);

	return 0;
}

2.2 类模板的实例化

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

int main()
{
	//int 类型的Stack
	Stack<int> st1;
	st1.Push(1);
	st1.Push(1);
	st1.Push(1);

	//double 类型的Stack
	Stack<double> st2;
	st2.Push(1.1);
	st2.Push(1.1);
	st2.Push(1.1);

	return 0;
}

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

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

相关文章

mlp与attention的计算时间复杂度分别为多少?PAtchtst为啥patch后为啥attention计算量降低?

感谢分享 看这篇博客的时候&#xff0c;因为patch后做了一个fc的映射&#xff0c;也是有计算的消耗嘛&#xff0c;好奇为什么说patchtst能够减小“注意力图的内存使用和计算复杂度减少了S倍&#xff0c;从而在计算资源有限的情况下允许模型查看更长的历史序列。“ 所以思考了一…

【时时三省】(C语言基础)循环语句while(2)

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ——csdn时时三省 getchar和scanf的作用 示例: int main ( ) &#xff5b; char password[20] ( 0 ) ; printf ( "请输入密码&#xff1a;> " )&#xff1b; scanf ( " &#xff05;s…

Redis:未授权访问

Redis Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的高性能键值对&#xff08;key-value&#xff09;数据库&#xff0c;支持多种类型的数据结构。 核心特性 内存存储&#xff1a;Redis将所有数据存储在内存中&#xff0c;能够提供极高的读写性能。 …

jumpserver web资源--远程应用发布机

1、环境 jumpserver:3.10.10 远程发布机&#xff1a;windows 2019 2、windows 2019准备 保证windows 正常登录&#xff0c;并且可以访问jumpserver 3、添加远程发布机 能正常连接就继续 可看到这里正常了 4、添加web资源 找到我们需要自动登录界面 获取相关元素选…

独立3D网络游戏《战域重甲》开发与上架经验分享

“ 小编阿麟&#xff1a;心之所向便是光&#xff0c;我们都是追光者!这位独立游戏开发者的产品能力已经不输给许多小团队&#xff0c;希望他的故事和经验分享&#xff0c;可以给走在同样道路上的朋友一些信心和帮助。 背景介绍 2023年年底的时候&#xff0c;我突然有一个很强的…

OpenGL3.3_C++_Windows(32)

demo SSAO SSAO 环境光照(Ambient Lighting)&#xff1a;光的散射&#xff0c;我们通过一个固定的常量作为环境光的模拟&#xff0c;但是这种固定的环境光并不能很好模拟散射&#xff0c;因为环境光不是一成不变的&#xff0c;环境光遮蔽&#xff1a;让&#xff08;褶皱、孔洞…

Qt Designer,仿作一个ui界面的练习(一):界面的基本布局

初学不要太复杂&#xff0c;先做一个结构简单的&#xff0c;大致规划一下功能分区&#xff0c;绘制草图&#xff1a; 最终的效果&#xff1a; 界面主要由顶边栏、侧边栏、内容区构成。顶边栏左边是logo&#xff0c;右边是时钟显示。侧边栏最上边是切换按钮&#xff0c;用以动画…

Notcoin 即将空投:你需要知道什么

Notcoin 于 2024 年 1 月推出&#xff0c;是 Telegram 上的一款边玩边赚游戏&#xff0c;用户可以通过点击硬币图标获得 Notcoin 代币 (NOT) 形式的奖励。NOT 建立在开放网络区块链&#xff08;称为“TON 区块链”&#xff09;上&#xff0c;由 Open Builders 创始人 Sasha Plo…

鸿蒙配置Version版本号,并获取其值

app.json5中配置版本号&#xff1a; 获取版本号&#xff1a; bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION).then((bundleInfo) > {let versionName bundleInfo.versionName; //应用版本号}).catch((error: BusinessE…

基于web的跨校区通勤车班次规划系统/校车管理系统

获取源码联系方式请查看文章结尾&#x1f345; 摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而…

STM32项目分享:智能台灯(机智云)系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 PCB图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.com/video/BV1My411q7fE…

常见的CSS属性(一)——字体、文本、边框、内边距、外边距、背景、行高、圆角、透明度、颜色值

一、字体 二、文本 三、边框 四、外边距 五、内边距 六、背景 七、行高 八、圆角 九、透明度 九、颜色值 元素的继承性是指给父元素设置了某些属性&#xff0c;子元素或后代元素也会有作用。 一、字体 “font-*”是字体相关的属性&#xff0c;具有继承性。代码如下&a…

长上下文语言模型与RAPTOR 方法

在科技领域的前沿&#xff0c;长上下文语言模型&#xff08;Long Context LLMs&#xff09;和新兴检索方法如RAPTOR 正在引发广泛关注。本文将围绕这些技术展开讨论&#xff0c;并探讨它们在实际应用中的创新性和科技性。 长上下文语言模型的崛起 近几周来&#xff0c;随着新型…

基于 SSM 的汽车租赁系统

基于 SSM 的电器网上订购系统 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;Spring、JSP、MyBatis 工具&#xff1a;MyEclipse/IDEA、Tomcat 引言 汽车租赁是在约定时间内&#xff0c;租赁经营人将租赁汽车&#xff08;包括载货汽车和载客汽车&#x…

前端在浏览器总报错,且获取请求头中token的值为null

前端请求总是失败说受跨域请求影响&#xff0c;但前后端配置已经没有问题了&#xff0c;如下&#xff1a; package com.example.shop_manage_sys.config;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Conf…

paddle ocr 文字识别模型训练 svtr

训练模型方法参考&#xff1a;https://github.com/PaddlePaddle/PaddleOCR/blob/main/doc/doc_ch/recognition.md 实践&#xff1a;https://aistudio.baidu.com/projectdetail/4482681 SVTR 算法原理 SVTR: Scene Text Recognition with a Single Visual Model Yongkun Du a…

Linux网络-ss命令

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注我&#xff0c;我尽量把自己会的都分享给大家&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux服务器作为一个常用的网络服务器&#xff0c;主要的作用就是向客户端提供网络…

数据结构(邓俊辉)学习笔记】高级搜索树03——红黑树

文章目录 1. 动机1.1 观察体验1.2 持久性1.3 关联性1.4 O&#xff08;1&#xff09;重构 2. 结构2.1 定义规则2.2 实例验证2.3 提升交换2.4 末端节点2.5 红黑树&#xff0c;即是B树2.6 平衡性2.7 接口定义 3. 插入3.1 以曲为直3.2 双红缺陷3.3 算法框架3.4 RR-13.5 RR-23.6 归纳…

将nvim的配置 上传gitee

首先是创建仓库 接着进入这个界面 然后是上传代码&#xff0c; 结果&#xff1a; 可以看到已经是可以了。 然后是 拉取代码进行测试。 第一次 拉取 使用 git clone .&#xff08;家里&#xff09; 做一点修改&#xff0c;然后上传。&#xff08;公司&#xff09; 然后在git pu…

Kotlin 的优势:现代编程语言的卓越选择

文章目录 简洁与优雅的语法空安全特性函数式编程&#xff0c;支持高阶函数、lambdaKotlin 内联函数与 Java 的互操作性强大的类型推断协程支持lazy 委托object 单例模式区间表达式现代的开发工具支持 本文首发地址 https://h89.cn/archives/301.html 最新更新地址 https://gite…