✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌟🌟 追风赶月莫停留 🌟🌟
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
🌟🌟 平芜尽处是春山🌟🌟
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅
🍋模版初阶
- 🍑泛型编程
- 🍍泛型编程的定义
- 🍍泛型编程的由来
- 🍍泛型编程的应用
- 🍑函数模版
- 🍍函数模版概念
- 🍍函数模版原理
- 🍍函数模版应用
- 🍍模版参数的匹配原则
- 🍑类模版
- 🍍类模版的概念
- 🍍类模版实例化
🍑泛型编程
🍍泛型编程的定义
在C++中,泛型编程是一种编程范式,它允许程序员编写与数据类型无关的代码。这样,你可以写出一段通用的代码,然后应用于多种数据类型,而不需要为每种数据类型都重新编写代码。泛型编程的核心概念是模板。
C++中有两种主要的模版:函数模版和类模版。
🍍泛型编程的由来
泛型编程的概念起源于对算法和数据结构通用性的追求。其最早的实践可以追溯到1970年代的CLU和Ada语言。在这些早期的语言中,程序员开始尝试编写不依赖于特定数据类型的通用算法。
随着时间的推移,泛型编程的概念逐渐发展并得到了更广泛的应用。1980年代,泛型编程开始被正式提出并应用于一些主流的编程语言中,如C++。C++引入了模板(template)机制,允许程序员编写可以处理多种数据类型的通用代码。
在1990年代,随着面向对象编程(OOP)的普及,泛型编程也开始被应用于面向对象的语言中,如Java。Java在J2SE 5.0(JDK 1.5)中引入了泛型技术,使得类和接口可以使用类型参数,进一步提高了代码的灵活性和重用性。
此后,泛型编程逐渐成为了现代编程语言中的一个重要特性,被广泛应用于数据结构、算法、框架等领域。它不仅提高了代码的重用性和灵活性,还增强了类型安全性,有助于减少运行时错误。
🍍泛型编程的应用
平常我们在解决一个算法时,需要构建一个函数来解决此算法,而这个函数我们需要写出通用的一个写法,不然没有什么意义,比如此函数可以解决参数为int型的,但解决不了类型为double型的,这就要你重新写一个函数可以解决类型为double的,这样就会很麻烦,比如:
int Add(int a, int b) { return a+b; } float Add(float a, float b) { return a+b; } double Add(double a, double b) { return a+b; }
上面三个加法函数只能解决自己类型的参数问题,算法相同,仅仅只是参数类型不同,这就很麻烦。
这就要提到我们今天的主角——模版,我们能不能通过给系统一个模版,然后编译器根据不同的类型来生成代码呢?
看下面分析,主要从函数模版和类模版介绍。
🍑函数模版
🍍函数模版概念
函数模板是C++泛型编程的一个重要组成部分,它允许程序员定义一种行为,该行为可以作用于多种不同的数据类型,而无需为每种数据类型都重新编写函数。函数模板通过引入类型参数(通常是使用typename或class关键字声明的),来创建一种可以处理多种数据类型的函数。
函数模板的定义使用template关键字开始,后面紧跟一个尖括号==,其中包含了类型参数列表==。类型参数类似于函数参数,但它们是用于指定函数内部使用的数据类型的。
🍍函数模版原理
函数模版的原理是基于数据类型的参数化,关键是将一组算法相同,但所处理数据类型不同的重载函数。
如:
template T Add(T a, T b) { return a+b; }
该用template修饰的Add()函数,就是一个加法函数的模版。
在编译器实际应用过程中并不是直接调用这个模版,而是间接通过模版构建一个关于此类型的加法函数,也就是上面那三个函数。
🍍函数模版应用
上图中,我们展示同类型参数传入的模版,如果两个参数是不同类型的该怎么写呢?
不同类型:
int Add(int a, float b) { return a+b; } float Add(int a, float b) { return a+b; } double (int a, double b) { return a+b; }
上面代码就是不同类型的参数,但实际返回还是看函数的类型,如第一个加法函数,虽然a是int类型,b是float类型,最后返回的确实int类型,因为此函数是int类型的。
那这个有没有模版呢?答案肯定是有的。
template T1 Add(T1 a, T2 b) { return a+b; }
上诉代码就是该类型模版的写法。
同样的道理,从图中我们可以看出,当需要用到此时函数时,并不是实际去调用这个函数,而是这个编译器可以根据你提供的这个模版,再根据你参数的类型自动生成这个类型的函数。
总结,关于这个函数模版,在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。
当我们知道这个模版的用法后,其实表面的工作由我们转到了编译器,编译器帮我们做了许多的工作。
🍍模版参数的匹配原则
关于这个模版参数的匹配原则,该程序中有该函数模版,但也有该类型的处理函数,那实际调用过程中,编译器会优先使用那个呢?接下来我直接用程序执行结果来给大家演示:
#include using namespace std; int Add(int a, int b) { cout cout int a = 2; int b = 8; int ret = Add(a, b); cout // 类内成员定义 };
还没有评论,来说两句吧...