当前位置: 首页 > news >正文

C++——模板初阶

文章目录

  • 一、前言
  • 二、模板——初阶
    • 2.1 再探重载
    • 2.2模板使用的原理
    • 2.3 模板的分类
      • 2.3.1 函数模板
        • 2.3.1.1 函数模板的概念
        • 2.3.1.2 函数模板的格式
        • 2.3.1.3函数模板的原理
        • 2.1.3.4 函数模板的两种实例化方式
      • 2.4 类模板
        • 2.4.1 类模板的定义格式
        • 2.4.2 类模板的实例化
      • 2.5 模板参数的匹配原则
  • 三、总结

一、前言

编程如同球场,唯有自己不断突破,才能取得最后的胜利
🚀鑫-萍的个人主页🚀
😀鑫-萍的Gittee仓库
🛬人生名言——与其被动迎敌,不如主动出击🛬
在这里插入图片描述

各位宝子们,今天是否又是活力满满的一天呢?学习之路有时候比较枯燥,所以我们更加要懂得如何放松自己,一味的盲目学习可是会适得其反的哦。一小碗鸡汤,先与大家共勉。好了,今天我们继续C++知识点的学习,今天要学习的内容是——模板初阶。

二、模板——初阶

2.1 再探重载

我们之前在学习函数重载的时候,会遇到这样一个问题——如何实现不同类型对象的Swap函数呢?
在一开始的时候,我们可能会这样来解决问题:

在这里插入图片描述

#include<iostream>
using namespace std;
void Swap(int& num1, int& num2)
{int tmp = num1;num1 = num2;num2 = tmp;
}
void Swap(double& num1, double& num2)
{double tmp = num1;num1 = num2;num2 = tmp;
}
void Swap(char& num1, char& num2)
{char tmp = num1;num1 = num2;num2 = tmp;
}
int main()
{int a1 = 1;int b1 = 2;cout << a1 << " "<<b1 << endl;Swap(a1, b1);cout << a1 << " " << b1 << endl;double a2 = 1.998;double b2 = 2.998;cout << a2 << " " << b2 << endl;Swap(a2, b2);cout << a2 << " " << b2 << endl;char a3 = 'y';char b3 = 'x';cout << a3 << " " << b3 << endl;Swap(a3, b3);cout << a3 << " " << b3 << endl;return 0;
}

这样的解决方法确实是实际可行的,但是现在虽然我们只有三种Swap重载,但是如果我们需要四种、九种甚至N种呢?要是按照之前的思路,一个一个地写重载函数,那整个工程的工程量未免太大了些。这时候有人会疑惑:有没有更加先进一点的方法呢?答案是肯定的。这时候模板的使用就可以通过一个泛型的模子来应对不同类型的实现需求。

在这里插入图片描述

#include<iostream>
using namespace std;
template <typename T>//定义一个模板
void Swap(T& num1, T& num2)
{T tmp = num1;num1 = num2;num2 = tmp;
}
int main()
{int a1 = 1;int b1 = 2;cout << a1 << " "<<b1 << endl;Swap(a1, b1);cout << a1 << " " << b1 << endl;double a2 = 1.998;double b2 = 2.998;cout << a2 << " " << b2 << endl;Swap(a2, b2);cout << a2 << " " << b2 << endl;char a3 = 'y';char b3 = 'x';cout << a3 << " " << b3 << endl;Swap(a3, b3);cout << a3 << " " << b3 << endl;return 0;
}

2.2模板使用的原理

经过两种不同方法的对比,我们更加实质上感受到的就是工程量的明显减少。那模板使用的原理又是什么呢?

在这里插入图片描述
在这里插入图片描述
在我们的陶瓷和手工业行业,就避免不了使用模具的情况,顾名思义,就是把你手上的材料导入一个固定的摸具之中,最后经过一系列加工,制作出外观与大小一致的样品。

那我们回到C++种,也会在这样的一个模具,通过给这个模具填充不同的类型的材料,来获得不同材料的铸件。
模板的使用是一种泛型编程。
泛型编程:缩写与类型无关的通用代码,是代码复用的一种手段。模板的泛型编程的基础。

2.3 模板的分类

在这里插入图片描述

2.3.1 函数模板

2.3.1.1 函数模板的概念

函数模板代表了一个函数家族,该函数的模板与类型无关,根据实参类型产生函数的特定类型版本。

2.3.1.2 函数模板的格式

template<typename T1,typename T2…。…typename Tn>
返回值类型 函数名(参数列表)[ ]

template //定义一个模板
void Swap(T& num1, T& num2) {
T tmp =num1;
num1 = num2;
num2 = tmp; }

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

2.3.1.3函数模板的原理

函数模板就如图一张修建房屋的工程图一样,它本身并不是函数,是编译器使用方式特定具体类型函数的模具,模板实际上把重复做的事情交给了编译器
在这里插入图片描述
编译器编译阶段,对于模板函数的使用,编译器需要传入的实参类型来推演生成的对应类型的函数

2.1.3.4 函数模板的两种实例化方式

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

在这里插入图片描述

#include <iostream>
using namespace std;
template<typename T>
//类模板
class Stack
{
public:Stack(size_t capacity = 4){_arr = new T[capacity];_capacity = capacity;_size = 0;}void Push(const T& data){_arr[_size] = data;++_size;}
private:T* _arr;size_t _capacity;size_t _size;
};
int main()
{//Stack是类名,Stack<int>才是类型Stack<int> st1; //intStack<double> st2; //doublereturn 0;
}

2.4 类模板

2.4.1 类模板的定义格式

在这里插入图片描述

2.4.2 类模板的实例化

与函数模板实例化不同,类模板实例化需要在类模板名字后面跟<>,然后将实例化的类型放在<>中即可
在这里插入图片描述

注意:类模板名字不是真正的类,类模板实例化出来的结果才是真正的类·

2.5 模板参数的匹配原则

1、一个非模板函数和一个同名的模板函数同时存在,而且该函数模板还可以被实例化为这个非模板函数;
2、对于非模板函数和同名模板函数,如果其他条件相同,在调用时会优先调用非模板函数,但如果该模板可以产生一个具有更好匹配的函数,那么将选择模板;
3、模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
在这里插入图片描述


#include <iostream>
using namespace std;
int Add(int num1, int num2)
{return num1 + num2;
}
template <typename  T>
T Add(T num1, T num2)
{return num1 + num2;
}
int main()
{cout << Add(1, 2) << endl;//与非模板函数匹配,不需要编译器转化cout << Add<int>(1, 2) << endl;//与模板函数匹配,会调用编译器转化的版本cout << Add(1, 2.333) << endl;//模板函数可以生成更加适配的版本,编译器会调用模板函数cout << Add<double>(1, 2.333) << endl;return 0;
}

三、总结

到这里,大家应该了解了重载与模板之间的关联了吧。也不能说谁一定比谁好,不过是在特定的环境下选择更加优越的方法而已,大家在实际使用的时候也要注意这一点。最后,希望大家好好消化,好好复习,继续前进!

http://www.dtcms.com/a/327097.html

相关文章:

  • 企业培训笔记:宠物信息管理--实现宠物信息的添加
  • 计算机毕设不知道选什么题目?基于Spark的糖尿病数据分析系统【Hadoop+Spark+python】
  • 多语言与隐形攻击:LLM安全防线为何被频频突破?
  • 雪花算法snowflake分布式id生成原理详解,以及对解决时钟回拨问题几种方案讨论
  • 跨设备开发不再难:HarmonyOS 分布式任务管理应用全解析
  • 【web站点安全开发】任务2:HTML5核心特性与元素详解
  • 树:数据结构中的层次架构
  • 【后端】Spring @Resource和@Autowired的用法和区别
  • 一键生成 Android 适配不同分辨率尺寸的图片
  • [GESP202309 六级] 2023年9月GESP C++六级上机题题解,附带讲解视频!
  • Airtable 入门指南:从创建项目到基础数据分析与可视化
  • 修复图像、视频和3D场景的AI工具–Inpaint Anything
  • PCIe Electrical Idle Sequences ( EIOS and EIEOS )
  • C++ 中的单例模式:使用静态方法管理唯一实例
  • 告别土味埋点:Java 优雅统计方法耗时的艺术与实践​
  • 企业高性能web服务器(4)
  • 【实时计费系统的Redis实践:视频平台按分钟付费服务的原子扣费与对账】
  • C++11-下
  • JPrint免费的Web静默打印控件:服务端口号修改
  • 医疗矫正流(MedRF)框架在数智化系统中的深度应用
  • 【bug 解决】串口输出字符乱码的问题
  • 【数据结构】——顺序表链表(超详细解析!!!)
  • 【KO】android 音视频
  • 打包工具:WebPack 和 Vite 对比
  • [激光原理与应用-254]:理论 - 几何光学 - 自动对焦在激光器中的应用?
  • 《吃透 C++ 类和对象(上):封装、实例化与 this 指针详解》
  • cpp-httplib 测试https功能
  • 告别数据孤岛!React 路由 3 种传参方法全解析
  • Apache Shiro
  • Gartner 《IAM for LLM-Based AI Agents》学习心得