c++之旅第九弹——模版

news2024/11/25 1:42:06

大家好啊,这里是c++之旅第九弹,跟随我的步伐来开始这一篇的学习吧!

如果有知识性错误,欢迎各位指正!!一起加油!!

创作不易,希望大家多多支持哦!

一.模版的概念:

1.泛型编程:

编写逻辑代码,适用于多种数据类型。

2.模版:

通过将类型定义为参数,实现了代码的重用性,即实现泛型编程。

二.函数模版:

1.函数模版不是实体函数,编译器不会对一个函数模板生成可执行代码;这只是一个函数功能的框架描述,只有在调用时有了具体的类型,生成了模版函数时才会生成可执行代码。

template:模板的关键字

<> :类型的参数列表

typename:用来声明类型参数,也可以用 class

2.函数模版使用:

int a=1,b=2;
char c='x';
​
template<typename T>//单类型
void fun(T &a,T &b)//&不是必须的格式
{
cout<<a<<endl<<b<<endl;
}
​
template <typename T1,typename T2>//双类型定义方式
void fun(T1 &a, T2 &b)

(1)、隐式推导类型:调用fun(a,b);正确 调用fun(a,c);错误,因为函数模板不会有隐式转换

(2)、显示指定类型:调用fun<int>(a,b);正确 调用fun<int>(a,c);也是正确的,因为显式指定类型后就生成了对应类型的实体函数,和普通函数一样,普通函数在编译器下可以进行可转换参数的转换,故此时也是正确的。//双类型的显式指定类型:fun<char, int>('a', 97);

(3)、函数模版类型参数列表中写普通形参就只能显式推导写法调用,eg:fun<int, 10>(12);不过一般这种写法不用于函数模版,因为可以将普通形参直接写在函数参数列表中,一般使用于类模板中。

3.函数模版和普通函数的区别:

(1)、函数模板和普通函数一样都是可以重载的,函数模板与普通函数也能构成重载

(2)、如果出现了函数模板与普通函数之间的重载,两者均满足时优先调用普通函数

(3)、如果函数模板可以产生一个更好的匹配,那么选择调用模板函数

(4) 、想要强制使用模板,那么就可以使用显式指定类型调用

4.函数模版的局限性:

eg:

template<typename T>
void fun(T &a,T &b)
{
cout<<a<<endl<<b<<endl;
}

若想使用该模版函数,但是传入的类型为自定义类类型,这样这个函数就无法执行了。

解决方式:

重载一个具体类型的函数来解决这个问题,Person 为自定义类型,其中有一个可以访问到的 x 成员

template<>void fun<Person>(Person&a,Person&b)
{
cout<<a.x<<endl<<b.x<<endl;
}

三.类模版:

1.类模板与函数模板类似,也不是一个实体的类,理解为一个类型的框架,所以类模板也需要生成具体的模板类,才能定义对象。

(1)写法1(只有类型参数):

template<typename T1 ,typename T2>

class 类模板名

{

成员函数和变量 ;

}

T1,T2 看作为类型的参数,在类中使用

(2)写法2(在类型参数列表中有形参):(eg:栈的实现)

template <class T,int maxSize>
class CMyStack  //自定义顺序栈
{
    T buff[maxSize];
    int top;
public:
    CMyStack()
    {
        top = 0;
    }
    void push(T const& elem)
    {
        buff[top++] = elem;
    }
    void pop()
    {
        top--;
    }
    T getTop() const
    {
        return buff[top - 1];
    }
    bool empty() const
    {
        return top == 0;
    }
};
CMyStack<int, 10> ms;//生成模板类后定义对象

2.类模板作为函数参数

(1)、做为函数的传入实参

void doWork(Person<string,int>& p){}

(2)、参数模板化

template<class T1,class T2>

void doWork(Person<T1,T2> &p){}

(3)、整体模板化

template<class T>

void doWork(T& p){}

3.类模板一般用于写数据结构类型,如数组,栈等。

4.类模板注意事项:

(1)类模板中成员函数要写在和类同一个头文件中类外的部分,不写到.cpp文件中

原因:因为.cpp文件是会参与编译的,而类模板在写的时候没有已知类型,故写在.cpp文件中的类中函数定义无法参与编译,也就相当于没有函数定义了;就算定义了一个模板类确定了类型,调用时写在.cpp文件中的函数体也不作数,使用时依然会报错(尝试得出),所以只有两种写法:直接定义在类中或者写在和类同一个头文件中的类外部分。

(2)template的类型参数T可以直接表示指针类型,但这样使用时会增加使用数据的不便,因为每次使用数据时都必须解引用进行操作,相对于普通类型(如int)的直接使用方式更加繁琐,所以一般也不会这样进行类型参数的使用。

(3)类模板继承情况:

①普通类的派生类为类模板情况:

class CA
{
};
template <class T>
class CB : public CA
{
};

②类模板的派生类新定义普通数据,但该派生类仍为类模板:

template <class T>
class CD
{   
T d;
};
template <class T>
class CE : public CD<T>
{   
int e;
};

③两者均包含的是模版:

template <class T1,class T2>
class CF : public CD<T1>
{
    T2 f;
};

(4)函数模版有显式和隐式推导,类模版只有显式推导;

模版函数和模版类在生成相对应实体或进行使用之前是不会报出函数模版和类模版的书写错误的(即实体化后才会保错),因为不参与编译。

5.类模板使用场景:

(1)泛型编程,是一种编写通用代码逻辑的方法,使其能够适用于多种数据类型。通过使用模板,我们可以定义通用的数据结构(如数组、链表、栈、队列等)和算法(如排序、查找、遍历等),从而处理不同类型的数据。

(2)C++标准库中的容器类库(如vector、list、map等)也是使用模板实现的。这些容器类模板允许存储和操作各种类型的数据,提供了方便、高效且类型安全的数据结构。 (3)另外,C++标准库中的迭代器也是通过模板实现的。迭代器模板允许对容器中的数据进行遍历和访问,而无需关心具体的容器类型。使用迭代器模板可以提供一种通用的访问方式,使得不同类型的容器可以以统一的方式进行操作。

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

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

相关文章

1分钟以上情感短视频素材去哪里找?推荐五个素材网站

在这个充斥着各种短视频的世界里&#xff0c;我就像是一名寻宝的冒险家&#xff0c;不断在素材的海洋中潜水&#xff0c;寻找那些能让我的视频金光闪闪的珍珠。让我告诉你&#xff0c;这不仅仅是一场寻宝&#xff0c;这简直是一场奇妙的冒险。九才素材网&#xff1a; 我的创作…

运用OSI模型提升排错能力

1. OSI模型有什么实际的应用价值&#xff1f; 2. 二层和三层网络的区别和应用&#xff1b; 3. 如何通过OSI模型提升组网排错能力&#xff1f; -- OSI - 开放式系统互联 - 一个互联标准 - 从软件和硬件 定义标准 - 不同厂商的设备 研发的技术 - 具备兼容性 -- O…

vim卡死了,没有反应怎么办?

解决办法&#xff1a; 很有可能是你有个在window下的好习惯&#xff0c;没事儿就ctrl s保存文件。但是在vim里&#xff0c;ctrl s默认是发送一种流控制信号&#xff0c;通常用于停止终端的输出&#xff0c;所以你的屏幕就卡死了。 解决办法也很简单&#xff0c;按下ctrl q即…

element-ui backtop 组件源码分享

今日简单分享 backtop 组件的源码实现&#xff0c;从以下三个方面&#xff1a; 1、backtop 组件页面结构 2、backtop 组件属性 3、backtop 组件事件 一、backtop 组件页面结构 二、backtop 组件属性 2.1 target 属性&#xff0c;触发滚动的对象&#xff0c;类型 string&am…

立方变自身-JavaB(6届)

public class L3 {public static void main(String[] args) {int cnt 0;//记录满足要求的个数//立方再往上&#xff0c;各位相加不会等于原数for (int i 1; i < 100; i) {//得到三次方int ans (int) Math.pow(i, 3);//得到立方的每位数相加int number get(ans);//判断是…

点击notify里面的通知,实现路由跳转

需求描述&#xff1a; 右上角有出来通知用户的有代办任务的消息框&#xff0c;点击消息框会跳转到代办路由页面。 duration:3000//弹窗显示时间, 毫秒 getElementsByClassName() – 获取所有指定类名的元素 效果展示&#xff1a;

基于 GPIO 、Pinctl子系统、设备树的LED 驱动程序

理论部分&#xff1a; 编写思路&#xff1a; GPIO 的地位跟其他模块&#xff0c;比如 I2C 、 UART 的地方是一样的&#xff0c;要使用某个引脚&#xff0c;需要先把引脚配置为 GPIO 功能&#xff0c;这要使用 Pinctrl 子系统&#xff0c;只需要在设备 树里指定就可以。在…

java:字符集和字符流

字符集 规定了字符和二进制之间对应关系的一张表 字节是计算机最基本的存储单位 字符则是通过字符组成和编码而成的文本 常见字符集 1,ASCII字符集 基础字符编码标准,包含128个字符,只包括英文字母,数字和一些常见的符号 一个字节表示一个字符 所有的字符集均兼容ASCII…

论文复现:nn.L1Loss()

nn.L1Loss() 是 PyTorch 中的一个损失函数&#xff0c;属于 torch.nn 模块的一部分。它计算预测值和真实值之间差的绝对值的平均值&#xff0c;也就是 L1 距离&#xff08;或曼哈顿距离&#xff09;。这个损失函数常用于回归任务&#xff0c;特别是当你希望减少异常值对总体损失…

Jenkins+AWS CodeCommit(git)

问题 需要使用Jenkins搭建一套CI流&#xff0c;即通过git代码托管拉取代码&#xff0c;构建自定分支的代码&#xff0c;构建出jar&#xff0c;并进一步构建出docker镜像&#xff0c;并推送到docker私有库中。 准备 AWS云准备 这里假设已经在CodeCommit已经存在私有git代码仓…

springCloudAlibaba集成sentinel实战(超详细)

一、Sentinel介绍 1. 什么是Sentinel Sentinel是阿里开源的项目&#xff0c;提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。 分布式系统的流量防卫兵&#xff1a; 随着微服务的普及&#xff0c;服务调用的稳定性变得越来越重要。Sentinel以“流…

纯css实现左右拖拽改变盒子大小

效果&#xff1a; 代码 <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html;charsetutf-8"><title></title><style>body {background-color: black;color: white;}.column {ove…

超2亿欧元,全球首个量子专项基金启动新一轮募资

今天&#xff0c;Quantonation宣布已完成其第二期基金的7000万欧元募资&#xff0c;计划到2025年初达到2亿欧元的规模。这家法国风险投资公司在全球范围内对量子计算、传感和通信应用领域的初创公司进行投资&#xff0c;主要关注于预种子轮和种子轮阶段。 其第一期基金在2021年…

2024/4/5—力扣—字符串相乘

代码实现&#xff1a; 方法一&#xff1a;常规解法——超出整数表示范围 long long char_to_num(char *str) {long long num 0;for (int i 0; i < strlen(str); i) {num num * 10 (str[i] - 0);}return num; }char* multiply(char *num1, char *num2) {long long a cha…

零基础教程|四步学会自制宣传手册

在当今竞争激烈的市场中&#xff0c;一本精美而引人注目的宣传手册是吸引客户和推广产品的重要工具。但对于许多人来说&#xff0c;制作宣传手册似乎是一项艰巨的任务&#xff0c;特别是对于零基础的人来说。然而&#xff0c;通过以下四个简单的步骤&#xff0c;您也可以轻松学…

每日两题 / 142. 环形链表 II 146. LRU 缓存(LeetCode热题100)

142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; 用哈希记录走过的节点即可 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:Lis…

Partisia Blockchain或被低估,有望在后续市场迎来爆发

在今年 3 月&#xff0c;隐私公链 Partisia Blockchain 迎来了重要的进展&#xff0c;该生态通证 $MPC 上线了交易所&#xff0c;目前 $MPC 通证可以在 Kucoin、Gate、BitMart、Bitfinex、Bitture 等平台交易&#xff0c;并将在不久后上线 MEXC 平台。 在上个月上线市场至今&am…

静态路由协议实验1

要求&#xff1a; 使用静态路由协议使得全网可达。 第一步、规划IP地址。并配置IP。 第二步、写静态路由 [r1]ip route-static 192.168.3.0 24 192.168.2.2 [r1]ip route-static 192.168.4.0 24 192.168.2.2 [r1]ip route-static 192.168.5.0 24 192.168.2.2[r2]ip route-st…

【JAVA基础篇教学】第三篇:Java循环控制语句

博主打算从0-1讲解下java基础教学&#xff0c;今天教学第三篇&#xff1a;Java循环控制语句。 在Java中&#xff0c;循环控制语句用于重复执行一段代码&#xff0c;直到满足特定条件为止。Java提供了多种类型的循环语句&#xff0c;包括for循环、while循环和do-while循环。 一…

广州南沙番禺联想SR530服务器主板传感器故障维修

今日分享一例广州市南沙区联想ThinkSystem SR530服务器sensor sysbrd vol故障问题维修案例&#xff1b; 服务器型号是&#xff1a;Lenovo thinksystem sr530 g6服务器 服务器所在位置&#xff1a;广东省广州市南沙区 服务器故障问题&#xff1a;机房异常停电&#xff0c;来电后…