C++基础语法——模板

news/2024/11/17 7:27:40/

1. 泛型编程

在平常的编写中,对于一个实现固定作用的函数,如交换两变量的值的Swap函数,对于不同类型只能编写相对应的重载函数,即

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

 对于这样的函数重载,有一些不利之处

1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数
2. 代码的可维护性比较低,一个出错可能所有的重载均出错

那我们能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?

答案是肯定的,而这又与泛型编程有关

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。

而在这之中模板是泛型编程的基础。模板也分为函数模板类模板  

2. 函数模板

①概念

函数模板是一种创建独立于数据类型的函数的方法,可以使用相同的代码处理不同的数据类型。

 函数模板由一个或多个类型参数组成,其中类型参数使用特殊的语法来声明为“typename”或“class”。在调用函数模板时,可以使用类型参数来指定实际参数类型,从而根据实际参数类型自动推导出函数模板的参数类型。

②使用

其格式举例如下

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

注:typename是用来定义模板参数关键字也可以使用class(切记:不能使用struct代替class)  

那我们就可以按如下格式来使用它

int main()
{double d1 = 2.0;double d2 = 5.0;Swap(d1, d2);int i1 = 10;int i2 = 20;Swap(i1, i2);char a = '0';char b = '9';Swap(a, b);return 0;
}

③原理 

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

④实例化 

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

⑴隐式实例化

即让编译器根据实参推演模板参数的实际类型

对于如下代码
template<class T>
T Add(const T& left, const T& right)
{return left + right;
}int main()
{int a1 = 10, a2 = 20;double d1 = 10.0, d2 = 20.0;Add(a1, a2);Add(d1, d2);// 注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅Add(a1, d1);// 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化Add(a1, (int)d1);return 0;
}

Add(d1, d2)语句不能通过编译,因为在编译期间,当编译器看到该实例化时,需要推演其实参类型通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T,编译器无法确定此处到底该将T确定为int 或者 double类型而报错

显式实例化

即在函数名后的<>中指定模板参数的实际类型

举例有

template<class T>
T Add(const T& left, const T& right)
{return left + right;
}int main()
{int a = 10;double b = 20.0;// 显式实例化Add<int>(a, b);return 0;
}
如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。

3. 类模板

①格式

其格式如下

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

具体举一个实例有

template<class T>
class Stack
{
public:Stack(size_t capacity = 3);void Push(const T& data);// 其他方法...~Stack(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}private:T* _array;int _capacity;int _size;
};template<class T>
Stack<T>::Stack(size_t capacity)
{/*_array = (T*)malloc(sizeof(T) * capacity);if (NULL == _array){perror("malloc申请空间失败!!!");return;}*/_array = new T[capacity];_capacity = capacity;_size = 0;
}template<class T>
void Stack<T>::Push(const T& data)
{// CheckCapacity();_array[_size] = data;_size++;
}

 在这之中我们发现,在实现类的成员函数时,要在前加上template。

②实例化

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

http://www.ppmy.cn/news/73389.html

相关文章

1.Buffer_Overflow-2.Stack_Overflow / 写入字符串

这道题虽然简单 但是却给我了另一个解题的看法 我们先进行运行 我们看看保护 发现只有NX保护 反汇编看看 发现有shellcode 但是我们没有办法执行shellcode 因为v5 不会等于后面的 这里我原本没有想法 后面进行看看他的汇编 这里其实就很清楚了 .text:00000000004011BB …

如何让你的 Jmeter+Ant 测试报告更具吸引力?

目录 引言 一、安装apache-Ant 二、Jmeter准备 3、生成测试报告 4、JMeter动态参数处理逻辑是什么&#xff1f; 5、JMeter是怎么做API自动化测试的&#xff1f; 结语 引言 想象一下&#xff0c;你辛苦搭建了一个复杂的网站&#xff0c;投入了大量的时间和精力进行开发和…

Linux 安装MySQL-5.7.30

本文总结在Linux上安装mysql数据库的方法以及遇到的问题。使用的环境信息 MySQL 5.7.30CentOS Linux release 7.6.1810 (Core) 1.官网下载MySQL 进入官网https://www.mysql.com/ 从下载页面下载社区版本其中社区版本免费&#xff0c;免费的午餐不提供技术支持. 页面中MySQL E…

第三十七章 弹灵守则第三十七条

“要不要一起玩&#xff1f;”那个跳来跳去的小男孩冲巴哥奔嘻嘻一笑。 “唔~” “很简单&#xff0c;这叫做玛丽的房间。”小男孩突然从她头顶跃过&#xff0c;脚尖点到她身后一块灰色方格。 “亮灰。” “D3D3D3。” “哈哈&#xff0c;你错了&#xff01;”头顶扎着一根小辫…

RK3568平台开发系列讲解(驱动基础篇)RK平台RTC的使用

🚀返回专栏总目录 文章目录 一、HYM8563模块二、HYM8563模块三、接口使用3.1 sysfs 接口3.2 procfs 接口3.3 ioctl 接口沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将对RK RTC的使用进行学习。 一、HYM8563模块 ROC-RK3568-PC开发板采用HYM8563作为RTC(Rea…

usb摄像头驱动-core层USB集线器(Hub)驱动

usb摄像头驱动-core层USB集线器&#xff08;Hub&#xff09;驱动 文章目录 usb摄像头驱动-core层USB集线器&#xff08;Hub&#xff09;驱动usb_hub_inithub_probehub_eventport_eventhub_port_connect_changehub_port_connectusb_new_deviceannounce_device 在USB摄像头驱动中…

二分查找怎么写? 你真的弄懂二分查找了吗

大家好&#xff0c;我是三叔&#xff0c;很高兴这期又和大家见面了&#xff0c;一个奋斗在互联网的打工人。 二分查找是一种高效的查找算法&#xff0c;也是Java中最基础的算法之一&#xff0c;常用于已排序数组中的元素查找。本篇博客将介绍二分查找的原理、应用场景以及实现…

多目标优化算法求解无人机三维路径规划

一、无人机模型 无人机三维路径规划是无人机在执行任务过程中的非常关键的环节&#xff0c;无人机三维路径规划的主要目的是在满足任务需求和自主飞行约束的基础上&#xff0c;计算出发点和目标点之间的最佳航路。 1.1路径成本 无人机三维路径规划的首要目标是寻找起飞点和目…