什么行业做网站多,水冷眸WordPress,企业咨询服务,休闲旅游产品营销网站的建设策略#x1f4dd;前言#xff1a; 在上一篇文章C内存管理中我们介绍了C的内存管理#xff0c;重点介绍了与C语言的区别#xff0c;以及new和delete。这篇文章我们将介绍C的利器——模板。 在C编程世界里#xff0c;模板是一项强大的特性#xff0c;它为泛型编程奠定了坚实基础…前言 在上一篇文章C内存管理中我们介绍了C的内存管理重点介绍了与C语言的区别以及new和delete。这篇文章我们将介绍C的利器——模板。 在C编程世界里模板是一项强大的特性它为泛型编程奠定了坚实基础。借助模板我们能够编写出与类型无关的通用代码极大地提升代码复用性减少重复劳动。接下来让我们深入探索C模板的奥秘。 个人简介努力学习ing 个人专栏C学习笔记 CSDN主页 愚润求学 其他专栏C语言入门基础python入门基础python刷题专栏 文章目录 一、函数模板1. 函数模板概念与格式2. 函数模板原理3. 函数模板实例化4. 模板参数匹配原则 二、类模板1. 类模板定义格式2. 类模板实例化 一、函数模板
1. 函数模板概念与格式
函数模板就像一个函数家族的蓝图该函数模板与类型无关在使用时被参数化编译器根据实参类型产生函数的特定类型版本。其格式如下
templatetypename T1, typename T2,......,typename Tn
返回值类型 函数名(参数列表){// 函数体
}其中typename是定义模板参数的关键字也可用class替代注意不能用struct。例如实现一个通用的加法函数模板
templatetypename T // 只有一
T Add(const T left, const T right) {return left right;
}2. 函数模板原理
函数模板本身并非真正的函数而是编译器用于生成具体类型函数的模具。在编译阶段编译器会依据传入的实参类型推演并生成相应类型的函数。比如
int main() {int a 10, b 20;double c 10.0, d 20.0;Add(a, b); // 编译器将T推演为int生成处理int类型的Add函数Add(c, d); // 编译器将T推演为double生成处理double类型的Add函数return 0;
}比如swap函数
3. 函数模板实例化
当程序中调用函数模板并为类型参数指定具体类型时编译器会根据该类型生成一个特定的函数实例。每个实例都是一个独立的函数可以像普通函数一样被调用和执行。
隐式实例化让编译器根据实参自动推演模板参数的实际类型。不过当实参类型无法唯一确定模板参数时会报错。例如
int main() {int a 10;double b 20.0;// Add(a, b); // 报错无法确定T的类型因为在这个模板的参数列表里面只有一个参数// 解决方法一用户强制类型转换Add(a, (int)b);// 解决方法二使用显式实例化Addint(a, b)return 0;
}显式实例化在函数名后的中明确指定模板参数的实际类型。如
int main() {int a 10;double b 20.0;Addint(a, b); return 0;
}多个参数的函数模版实例
#include iostream// 函数模板接受多个参数并打印它们
templatetypename T1, typename T2, typename T3
void printMultiple(const T1 a, const T2 b, const T3 c) {std::cout Values are: a , b , c std::endl;
}int main() {int intValue 1;double doubleValue 2.5;char charValue A;printMultiple(intValue, doubleValue, charValue);// 显式实例化printMultipleint, double, char(intValue, doubleValue, charValue);return 0;
}4. 模板参数匹配原则
一个非模板函数可以和同名函数模板共存且函数模板能实例化为该非模板函数。调用时若其他条件相同优先调用非模板函数若模板能生成更匹配的函数则选择模板。模板函数不允许自动类型转换普通函数可以。例如
// 专门处理int的加法函数
int Add(int left, int right) {return left right;
}
// 通用加法函数
templateclass T
T Add(T left, T right) {return left right;
}
void Test() {Add(1, 2); // 调用非模板函数Addint(1, 2); // 调用模板函数实例化版本Add(1, 2.0); // 调用模板函数生成的更匹配版本
}二、类模板
1. 类模板定义格式
templateclass T1, class T2, ..., class Tn
class 类模板名 {// 类内成员定义
};以实现一个简单的栈类模板为例
templatetypename T
class Stack {
public:Stack(size_t capacity 4) {_array new T[capacity];_capacity capacity;_size 0;}void Push(const T data);
private:T* _array;size_t _capacity;size_t _size;
};
templateclass T
void StackT::Push(const T data) {// 扩容逻辑_array[_size] data;_size;
}注意类模板中可以定义成员函数模版但是类模板里面的成员函数不一定是函数模版。
2. 类模板实例化
类模板实例化必须是显式实例化即需要在类模板名字后跟并将实例化类型置于其中。类模板本身不是真正的类实例化结果才是。例如
int main() {Stackint st1; // 实例化出处理int类型的栈Stackdouble st2; // 实例化出处理double类型的栈return 0;
}注意模版不建议声明和定义分离到两个文件.h和.cpp会出现链接错误 我的分享也就到此结束啦 要是我的分享也能对你的学习起到帮助那简直是太酷啦 若有不足还请大家多多指正我们一起学习交流 公主王子点赞→收藏⭐→关注 感谢大家的观看和支持祝大家都能得偿所愿天天开心