行业知识
【爱上C++】函数模板 (1)
2026-11-03 07:02:48
来源:互联网转载
目录
- 一 泛型编程
- 1.定义
- 2. 引入
- 二 函数模板
- 1. 函数模板的概念
- 2. 函数模板的格式
- 3.函数模板的原理
- 4.函数模板的实例化
- 5.显式实例化
- 6.模板参数的匹配原则
- 三 类模板
- 1.类模板的定义格式
- 2.类模板的实例化
一 泛型编程
1.定义
泛型编程(Generic Programming)是一种编程范式,它旨在编写与数据类型无关的代码。通过这种方式,程序员可以编写出灵活且可重用的代码,这些代码可以对不同类型的数据进行操作,而无需为每种数据类型编写特定的代码。泛型编程主要依赖于模板(Templates)来实现,模板是一种允许程序员在一种类型不确定的情况下,编写通用的代码。
2. 引入
C语言中想要实现两个数进行交换可以用 异或,或者用临时变量tmp。
比如我们想要交换a,b的值,可以用一个Swap函数
void Swap(int *a,int *b){//用指针的方法int tmp=*a;*a=*b;*b=tmp;}void Swap1(int& a,int &b){//用引用的方法int tmp=a;a=b;b=tmp;}int main(){int a=0,b=1;Swap(&a,&b);return 0;}但是如果我又想要交换两个double类型的变量,怎么办?再写一个double* 的Swap?那我又想要交换char类型的呢?是不是还要写,这样是不是很麻烦。哎!我们前面学了函数重载,但如果再有一种类型是不是还要再写一遍?
使用函数重载虽然可以实现,但是有一下几个不好的地方:
- 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函
数
- 代码的可维护性比较低,一个出错可能所有的重载均出错
那能否告诉编译器一个模子,让编译器根据不同的类型利用该模子来生成代码呢?
如果在C++中,也能够存在这样一个模具,通过给这个模具中填充不同材料(类型),来获得不同材料的铸件
(即生成具体类型的代码),那将会节省许多头发。巧的是前人早已将树栽好,我们只需在此乘凉。
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。
这时 函数模板就派上用场了。
二 函数模板
1. 函数模板的概念
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定
类型版本。
2. 函数模板的格式
template
即:返回值类型 函数名(参数列表){}
例如:
template void Swap(T& left,T& right)//注意right不要写错啦,刚刚就写错了{T tmp=left;left=right;right=tmp;}int main(){int a=1,b=2;double c=3.0,d=4.0;char e='x',f='y';Swap(a, b);Swap(c, d);Swap(e, f);coutreturn left+right}int main(){int a=1,b=0;double c=1.0,b=2.0;Add(a,b);Add(c,d);return 0;}int a = 10;double b = 20.13;cout return left + right;}// 函数模板templatereturn left + right;}int main(){// 匹配调用原则:// 1、合适匹配的情况下,有现成的就吃现成// 2、没有就将就吃// 3、有更合适就吃更合适的,哪怕要自己现做coutreturn new T[n];}int main(){//funcreturn left + right;}// 通用加法函数templatereturn left + right;}void Test(){Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化Add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数} int temp = a; a = b; b = temp;}// 模板函数不支持自动类型转换template T temp = a; a = b; b = temp;}int main() { int x = 5; double y = 3.14; cout public:Stack(int capacity = 4) : _top(0) , _capacity(capacity) {_arr = new int[capacity];}~Stack() {delete[] _arr;_arr = nullptr;_capacity = _top = 0;}private:int* _arr;int _top;int _capacity;};Stack st1;//我们想存int数据Stack st2;//我们想存double数据return 0;}// 类内成员定义};public:Stack(T capacity = 4): _top(0), _capacity(capacity) {_arr = new T[capacity];}~Stack() {delete[] _arr;_arr = nullptr;_capacity = _top = 0;}private:T* _arr;int _top;int _capacity;};int main(void){Stack st1; // 存储intStack st2; // 存储doublereturn 0;}public://构造函数 (函数名和类名相同,不是类型名) 不写Stackcout //...}private:T* _a;int _top;int _capacity;};//声明和定义分离的话要这样写(也不能放到两个文件,只能放到一个文件里,至于为何模板进阶的时候会讲)//定义templatecout // 类模板都是显示实例化Stack - 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函
上一篇:服务器的cpu怎么监控?
下一篇:怎么让流量飞起?