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

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 = 1cout << "i = " << i << "\t" << "j = " << j << endl;//i = 5.20 , j = 13.14return 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 = 1cout << "i = " << i << "\t" << "j = " << j << endl;//i = 5.20 , j = 13.14return 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;//5cout << Add<double>(x, y) << endl;//5.14return 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;//5cout << Add<double>(x, y) << endl;//5.14//推到实例化cout << Add(x, (int)y) << endl;cout << Add((double)x, y) << endl;//新的函数模版cout << Add(x, y) << endl;//5return 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;//30return 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 类型的StackStack<int> st1;st1.Push(1);st1.Push(1);st1.Push(1);//double 类型的StackStack<double> st2;st2.Push(1.1);st2.Push(1.1);st2.Push(1.1);return 0;
}

2.2 类模板的实例化

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

int main()
{//int 类型的StackStack<int> st1;st1.Push(1);st1.Push(1);st1.Push(1);//double 类型的StackStack<double> st2;st2.Push(1.1);st2.Push(1.1);st2.Push(1.1);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于ant-design-vue3多功能操作表格,表头序号为动态添加记录按钮,鼠标在表格记录行,当前行序号显示删除按钮

由于项目需要&#xff0c;并考虑到尽可能让空间利用率高&#xff0c;因此定制开发一个表格组件&#xff0c;组件功能主要是在序号表头位置为添加按钮&#xff0c;点击按钮&#xff0c;新增一行表格数据&#xff1b;表格数据删除不同于以往表格在操作栏定义删除按钮&#xff0c;…

问题解决|如何优雅展示层级或关联数据?

一、8种可用图表类型及配套教程 &#xff08;一&#xff09;包珠图 &#xff08;1&#xff09;功能介绍 包珠图&#xff08;Circular Packing&#xff09;&#xff0c;是一类较特殊的分类树状图&#xff0c;以气泡之间的包含关系展示层级关系&#xff0c;以气泡面积&#xf…

Spring事件机制

文章目录 一、Spring事件二、实现Spring事件1、自定义事件2、事件监听器2.1 实现ApplicationListener接口2.2 EventListener2.3 TransactionalEventListener 3、事件发布4、异步使用 三、EventBus1、事件模式2、EventBus三要素3、同步事件3.1 定义事件类3.2 定义事件监听3.3 测…

解析西门子PLC的String和WString

西门子PLC有两种字符串类型&#xff0c;String与WString String 用于存放英文数字标点符号等ASCII字符&#xff0c;每个字符占用一个字节 WString宽字符串用于存放中文、英文、数字等Unicode字符&#xff0c;每个字符占用两个字节 之前我搞过一篇解析String的 关于使用TCP-…

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

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

包装类和泛型

&#x1f389;欢迎大家收看&#xff0c;请多多支持&#x1f339; &#x1f970;关注小哇&#xff0c;和我一起成长&#x1f680;个人主页&#x1f680; 包装类&#x1f319; Java中每个基本数据类型都对应了一个包装类&#xff0c; 除了int的包装类是Integer&#xff0c;char…

微信小程序开发 快速学习 这篇就够了

目录 一、配置篇 &#xff08;1&#xff09;官网链接&#xff1a; &#xff08;2&#xff09;项目分析 &#xff08;3&#xff09;调试器 &#xff08;4&#xff09;预览体验 &#xff08;5&#xff09;配置文件 &#xff08;6&#xff09;配置pages &#xff08;7&…

【开发问题记录】启动某个微服务时无法连接到seata(seata启动或配置异常)

问题记录 一、问题描述1.1 问题复现1.1.1 将Linux中的部分微服务启动1.1.2 在本地启动当时出错的服务 1.2 解决思路1.2.1 Nacos中seata相关的信息1.2.2 Linux中seata相关的信息 二、问题解决2.1 seata的配置错误2.1.1 Nacos中seata的配置问题2.1.2 命名空间问题的发现 2.2 网络…

Matlab编程资源库(10)离散傅立叶变换

一、离散傅立叶变换算法简要 给定一个N点的离散信号序列x(n)&#xff0c;其中n表示时刻&#xff0c;n 0, 1, 2, ..., N-1。 定义离散傅立叶变换的频域序列X(k)&#xff0c;其中k表示频率&#xff0c;k 0, 1, 2, ..., N-1。 通过以下公式计算每个频率对应的复数值&#xff…

生鲜云订单零售系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商品分类管理&#xff0c;商品信息管理&#xff0c;订单评价管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;商品信息&#…

[Unity] ShaderGraph实现镜头加速线/残血效果 URP

效果如下所示&#xff1a;残血状态时&#xff0c;画面会压暗角&#xff0c;并出现速度线营造紧迫感。 使用到的素材如下&#xff0c;换别的当然也可以。[这是张白色的png放射图&#xff0c;并非皇帝的新图hhh] 这个效果的实现逻辑&#xff0c;其实就是利用time向圆心做透明度的…

2024经济师考试报名『注册流程』图解!

⏰报名时间&#xff1a;8月12日—9月11日 ☑️报名注册流程 1、经济师考试报名注册网站&#xff1a;中国人事考试网. 2、点击考生登录栏目中的【新用户注册】按钮&#xff0c;进行注册。 3、进入用户注册界面&#xff0c;填写注册信息。 4、填写完毕确认无误后点击【提交】&…

Unity UGUI 之 Mask

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 本文在发布时间选用unity 2022.3.8稳定版本&#xff0c;请注意分别 1.什么是遮罩 遮罩是一…

深度解读大语言模型中的Transformer架构

一、Transformer的诞生背景 传统的循环神经网络&#xff08;RNN&#xff09;和长短期记忆网络&#xff08;LSTM&#xff09;在处理自然语言时存在诸多局限性。RNN 由于其递归的结构&#xff0c;在处理长序列时容易出现梯度消失和梯度爆炸的问题。这导致模型难以捕捉长距离的依…

学习react-登录状态验证

1.创建三个页面LoginPage, HomePage,NotFoundPage用于Router 创建LoginPage.tsx用于做登录页面 // LoginPage.tsx const LoginPage (props:LoginProp) > {const navigate useNavigate();return( <h1 onClick{ ()>{navigate("/");}}>Hello Login, {pr…

02 Go语言操作MySQL基础教程_20240729 课程笔记

概述 如果您没有Golang的基础&#xff0c;应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础Go语言开发REST API接口_20240728 基础不好的同学每节课的代码最好配合视频进行阅读和学习&#xff0c;如果基础比较扎实&#xff0c;则阅读本教程巩固一下相…

微信小游戏之 三消(一)

首先设定一下 单个 方块 cell 类&#xff1a; 类定义和属性 init 方法 用于初始化方块&#xff0c;接收游戏实例、数据、宽度、道具类型和位置。 onWarning 方法 设置警告精灵的帧&#xff0c;并播放闪烁动作&#xff0c;用于显示方块的警告状态。 grow 方法 根据传入的方向…

21.发布确认模式-高级

问题 生产环境中由于一些不明原因&#xff0c;导致rabbitmq重启&#xff0c;在重启的期间生产者消息投递失败&#xff0c;导致消息丢失&#xff0c;需要手动处理恢复。那么如何才能进行rabbitmq的消息可靠性投递&#xff1f;特别是在极端的情况&#xff0c;rabbitmq集群不可用…

文件操作相关的精讲

目录&#xff1a; 思维导图 一. 文件定义 二. 文件的打开和关闭 三. 文件的顺序读写操作 四. 文件的随机读写操作 五. 文本文件和二进制文件 六. 文件读取结束的判断 七.文件缓冲区 思维导图&#xff1a; 一. 文件定义 1.文件定义 C语言中&#xff0c;文件是指一组相…

Vue3可媲美Element Plus Tree组件实战之移除节点

Element Plus Tree自定义节点内容示例中介绍了移除节点的用法&#xff0c;个人觉得作为提供给用户API&#xff0c;应该遵循迪米特法则&#xff0c;把功能实现的细节封装在组件内部&#xff0c;而提供给用户最简单的操作方式&#xff0c;同时在此基础上支持用户的扩展。 因此&a…