引入
哈喽各位铁汁们好啊,我是博主鸽芷咕《C++干货基地》是由我的襄阳家乡零食基地有感而发,不知道各位的城市有没有这种实惠又全面的零食基地呢?C++ 本身作为一门篇底层的一种语言,世面的免费课程大多都没有教明白。所以本篇专栏的内容全是干货让大家从底层了解C++,把更多的知识由抽象到简单通俗易懂。
⛳️ 推荐
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
文章目录
- 引入
- ⛳️ 推荐
- 一、模版的概念
- 1.1 模版的概念提出
- 1.2 模版函数的格式
- 1.3 模版的原理
- 二、函数模版
- 2.1 函数模板的实例化
- 隐式实例化
- 显式实例化
- 2.2模板参数的匹配原则
- 三、类模版
- 3.1 类模板的定义格式
- 3.2 类模板的实例化
- 四、模版带来的改变?
- 4.1 STL 的出现
- 五、图书推荐
- 5.1 码农修行 编写优雅代码的了32条法则
- 5.2 图书简介
- 5.3 图书内容
- 5.4 购买连接
- 六、 粉丝福利&参与规则
一、模版的概念
1.1 模版的概念提出
虽然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;
}
......
那么我们是否可以让编译器像活字印刷一样,需要那种类型的函数直接生成一个就好了?
- 我们能想到的点祖师爷自然也能想到所以在C++中有模版的语法来帮我们解决代码冗余的问题来提高通用性。
1.2 模版函数的格式
template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表)
{
//函数的实现
}
- 下面我们就来使用模版的格式来写一个通用的交换函数吧!
template<typename T>
void Swap( T& left, T& right)
{
T temp = left;
left = right;
right = temp;
}
1.3 模版的原理
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用
- 比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。
- 而我们通过汇编代码也可以看出来编译器通过模版来生成不同的交换函数
二、函数模版
2.1 函数模板的实例化
隐式实例化
- 隐式实例化:让编译器根据实参推演模板参数的实际类型
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
int main()
{
int a1 = 10, a2 = 20;
double d1 = 10.0, d2 = 20.0;
Add(a1, a2);
Add(d1, d2)
return 0;
}
这个我相信大家理解,就正常使用函数就好了,但有时候我们需要模版只定义了一种类型但我们却传了俩种类型不同的数据这时候就会出现报错了如果想让它继续运行的话,就得使用显式实例化或者自己强制转换为一样的类型。
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
int main()
{
int a1 = 10, a2 = 20;
double d1 = 10.0, d2 = 20.0;
Add(a1, a2);
Add(d1, d2);
Add(a1, (int)d1);
return 0;
}
显式实例化
- 显式实例化:在函数名后的
<>
中指定模板参数的实际类型
int main(void)
{
int a = 10;
double b = 20.0;
// 显式实例化
Add<int>(a, b);
return 0;
}
2.2模板参数的匹配原则
- 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数
// 专门处理int的加法函数
int Add(int left, int right)
{
return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right)
{
return left + right;
}
void Test()
{
Add(1, 2); // 与非模板函数匹配,编译器不需要特化
Add<int>(1, 2); // 调用编译器特化的Add版本
}
int main()
{
Test();
return 0;
}
- 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板
// 专门处理int的加法函数
int Add(int left, int right)
{
return left + right;
}
// 通用加法函数
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{
return left + right;
}
void Test()
{
Add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化
Add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函
}
三、类模版
3.1 类模板的定义格式
template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};
template<class T>
class Stack
{
public:
void push(const T& x);
private:
T* _a;
int _top;
int _capacity;
};
// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template<class T>
void Stack<T>::push(const T& x)
{
//...
}
int main()
{
// 同一个类模板实例化出的两个类型
Stack<int> s1;
Stack<double> s2;
return 0;
}
3.2 类模板的实例化
类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。
Stack<int> s1;
Stack<double> s2;
四、模版带来的改变?
4.1 STL 的出现
模版的出现使的我们代码的通用性和扩展性更高,以往我们库函数想要支持交换函数很麻烦。但是有了模版我们只需呀写一个库模版就可以支持不同类型的库函数。
- 比如说我们的 数据结构 如果是C语言我们想要不同类型的数据结构来存储数据就需要好几种所以C语言库里没有数据结构的库函数。
- 而C++ 有了模版只需要写一个数据结构模版就可以实现存不同类型数据的需求了,这也是我们后面需要学习的容器。
- 所以可以说模版是C++最大的精华,有了模版才有后来的STL 容器等等。
五、图书推荐
5.1 码农修行 编写优雅代码的了32条法则
5.2 图书简介
如何打造精品软件一直是软件行业讨论的热点话题。初入职场的软件开发人员,多数都只是在学会了某种编程语言后就直接进行编程工作。但由于他们并未掌握编程中的一些有效方法,导致其开发的软件问题累累且工作效率不高。《码农修行》编写优雅代码的32条法则针对这类人群提出了一些改善编程方法的建议,涉及具体编程工作的诸多方面,偏重于实践。书中大部分示例都是笔者实际编程工作中碰到过的真实案例,具有较高的参考价值。
《码农修行》编写优雅代码的32条法则从代码的可 读性、可靠性、效率、可维护性、可扩展性5个方面,提出了编写代码的32 条法则 。此外还公开了笔者自主编写的一款Android 小游戏源代码,希望能对读者有所帮助。《码农修行》编写优雅代码的32条法则适用于有一定编程基础、且想进一步提升个人编程能力的读者阅读,也可作为大中专院校计算机专业师生的教学参考用书。
5.3 图书内容
5.4 购买连接
京东连接: https://item.jd.com/12711115.html
六、 粉丝福利&参与规则
-
✅参与方式:
关注
博主、点赞
、收藏
、评论
,任意评论(每人最多评论三次) -
⛳️本次送书
5
本【取决于阅读量,阅读量越多,送的越多
】 -
📆 活动时间至:2024-2-27 20:00:00 | 随机抽取由博主动态公布抽奖结果
如有特别需要的同学可添加博主微信进入粉丝福利群发放福利哦!
🔥 注:活动结束后,会私信中奖粉丝的,各位注意查看私信哦!