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

【C++】——初识模版

文章目录

  • 前言
  • 函数模版
    • 函数模版的原理
    • 函数模版的实例化
  • 类模版
    • 类模版的实例化

前言

当我们使用一个通用的函数:

//为每一个类型都编写一个重载版本
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;
}

这种方法的缺点是显而易见的:随着需要交换的类型的增加,你需要不断地编写新的重载函数。这不仅繁琐,而且不灵活,因为它不能自动适应未来可能出现的新类型。

函数模板提供了一种更加灵活和通用的解决方案。你可以定义一个模板函数,该函数可以接受任意类型的参数,并在编译时根据传入的参数类型生成相应的函数版本。

函数模版

函数模版的格式:
template<typename T1, typename T2,…,typename Tn>
返回值类型 函数名(参数列表){}

//函数模版
template<class T>
void Swap(T& m, T& n)
{T tmp = m;m = n;n = tmp;
}

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

template<typename T>
void Swap(T& m, T& n)
{T temp = m;m = n;n = temp;
}
template<class T>
void Swap(T& m, T& n)
{T tmp = m;m = n;n = tmp;
}
int main()
{int i = 1, j = 2;double x = 1.1, y = 2.2;Swap(i, j);Swap(x, y);//Swap(i, x); 函数模版不能传不同类型的参数return 0;
}

函数模版的原理

函数模版本身并不是函数,模版只是将我们做的事重复的事交给了编译器
在这里插入图片描述

函数模版的实例化

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

这里就是要解决这个问题在这里插入图片描述

有两种处理方式

  1. 强制类型转换
  2. 使用显式实例化
template<class T>
void Swap(const T& m, const T& n)
{T tmp = m;m = n;n = tmp;
}
int main()
{int i = 1, j = 2;double x = 1.1, y = 2.2;//推导实例化(自己动手强转)Swap(i, (int)x);Swap((double)i, x);//显示实例化Swap<int>(i, x);return 0;
}

如果我就要用 Swap(i,x) 来实现呢?

template<class T1,class T2>
T1 Swap(const T1& m, const T2& n)
{T1 tmp = m;m = n;n = tmp;
}

有种场景我们必须用显示实例化:

template<class T>
T* func1(int n)
{return new T[n];
}
int main()
{//func1(10); 编译器无法推导出类型int* p = func1<int>(10);return 0;
}

如果函数和模板同时存在,会先调用函数

template<class T>
T ADD(const T& left, const T& right)
{return left + right;
}
int ADD(const int& x, const int& y)
{return (x + y) * 10;
}
int main()
{int a = 5;int b = 10;cout<<ADD(a, b)<<endl;return 0;
}

在这里插入图片描述

类模版

类模版的格式:

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

类模版实现栈

template<class T>
class Stack
{
public:Stack(int n = 4):_arr(new T[n]),_size(0),_capacity(n){}~Stack(){delete[] _arr;_arr = nullptr;_size = _capacity = 0;}void Push(const T& x){if (_size == _capacity){T* tmp = new T[_capacity * 2];memcpy(tmp, _arr, sizeof(T) * _size);delete[] _arr;_arr = tmp;_capacity *= 2;}_arr[_size++] = x;}//...
private:T* _arr;int _size;int _capacity;
};

将栈的所有数据和方法封装在类内部,所以只有类成员函数才可以访问(最好不要类里声明,类外定义,除非在类外使用template<>语法来指明你正在定义的是哪个模板参数的成员函数),而且,通过类模版,不同的类型都可以实现栈,安全性也得到了提升。

template<class T>
void Stack<T>::Push(const T& x)
{if (_size == _capacity){T* tmp = new T[_capacity * 2];memcpy(tmp, _arr, sizeof(T) * _size);delete[] _arr;_arr = tmp;_capacity *= 2;}_arr[_size++] = x;
}

类模版的实例化

类模版只能使用显示实例化

int main()
{Stack<int>str1;str1.Push(1);str1.Push(2);str1.Push(3);Stack<double>str2;str2.Push(1.1);str2.Push(2.2);str2.Push(3.3);return 0;
}

希望这篇博客对你有所帮助!!!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • .NET单元测试使用AutoFixture按需填充的方法总结
  • VAE论文阅读
  • 2024中国大学生算法设计超级联赛(1)
  • 消费金融系统开发回忆录
  • 《昇思 25 天学习打卡营第 14 天 | 基于MindSpore的红酒分类实验 》
  • 代码解读:Diffusion Models中的长宽桶技术(Aspect Ratio Bucketing)
  • Android 15 之如何快速适配 16K Page Size
  • Spring Boot 学习(10)——固基(Idea 配置 git 访问 gitee)
  • JSON字符串介绍
  • 【深度学习图像】拼接图的切分
  • GIS技能应用(1)
  • Web前端:HTML篇(二)元素属性
  • SpringBoot缓存注解使用
  • 如何在Linux中打开core文件
  • 【手撕数据结构】拿捏单链表
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • CSS实用技巧
  • echarts的各种常用效果展示
  • PermissionScope Swift4 兼容问题
  • React Native移动开发实战-3-实现页面间的数据传递
  • 初识 webpack
  • 理清楚Vue的结构
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 前端学习笔记之观察者模式
  • 如何胜任知名企业的商业数据分析师?
  • 学习使用ExpressJS 4.0中的新Router
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ## 1.3.Git命令
  • #define 用法
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • $.ajax中的eval及dataType
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (3)选择元素——(17)练习(Exercises)
  • (4)(4.6) Triducer
  • (4)Elastix图像配准:3D图像
  • (php伪随机数生成)[GWCTF 2019]枯燥的抽奖
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (八十八)VFL语言初步 - 实现布局
  • (二开)Flink 修改源码拓展 SQL 语法
  • (二刷)代码随想录第16天|104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (十六)Flask之蓝图
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转)winform之ListView
  • ******之网络***——物理***
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .bat批处理(一):@echo off
  • .CSS-hover 的解释
  • .net MySql
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项