前言
今天简单和大家分享一下C++重要的两个内容,经过之前的学习我们已经了解了C++的大致语法,接下来就是C++相关的库和一些操作了,他们能极大地缩小我们C语言阶段的代码量,让写代码变得轻松起来。
1.关于模版
<1>泛型编程
我们学过函数重载之后,我们知道参数的类型不同就可以写n个函数重载,比如swap函数,底层的交换逻辑是很简单的,但我们重载却要写很多函数,很麻烦。
在C++中就有了模版这一概念,将这个过程交给编译器去做,大大减少了程序员的工作量
模版有函数模版和类模版之分,我们先来介绍函数模版。
<2>函数模版的格式
typename也可以用class来替换,他们都是用来定义模版的关键字
template<typename T>
void Swap( T& left, T& right)
{
T temp = left;
left = right;
right = temp;
}
<3>函数模版的原理
函数模版并不是函数,他们相当于蓝图,调用它们的时候再由编译器根据基本逻辑和实参去实现一个符合要求的基本函数。
也就是说函数模版可以根据实参自动识别并生成符合的函数,这个过程由编译器去完善和实现。
这里涉及到隐式实例化和显示实例化。
(1)隐式实例化
关于隐式实例化依靠的是模版的自动识别特性,举个例子;
int main()
{
int a=9,b=10;
double c = 1.0 ,d = 2.0;
swap(a,b);
swap(c,d);
return 0;
}
(2)显示实例化
关于显示实例化就是在函数名后实现用 <类型> 显示所要实现的类型
int main(void)
{
int a = 10;
double b = 20.0;
// 显式实例化
Add<int>(a, b);
return 0;
}
(3)
模版函数和全局函数可以同时存在,什么意思呢,我们可以写一个模版函数,我们可以再写一个同名逻辑相同的函数,二者可以同时存在,就像这样:
int Add(int left, int right)
{
return left + right;
}
template<class T>
T Add(T left, T right)
{
return left + right;
}
这样就会产生一个问题,编译器到底会使用那个函数:
它有这样一个原则:有现成的吃现成,也就是说非模版函数能满足我们的需求,那么我们就使用非模版函数。
如果说模版函数能提供给我们一共更符合的,那么编译器就会使用模版函数。
<4>类模版
关于类模版,与函数模版有很多相似的地方,但略有差别
关于类模版的用处,我们可以想到学习过的栈,队列这样的数据结构,我们在C语言阶段实现的时候,对于数据类型我们通常是typedef 某个数据类型为StackDateType等等,在这里我们完全可以使用类模版,来代替这个栈或队列等数据结构的数据类型,比如下面这个例子:
template<typename 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;
};
模版类不建议声明和链接分开定义会出现链接报错;
但是在类模版这里我们只能使用显示实例化,比如说这样去实现。
int main()
{
// Stack是类名,Stack<int>才是类型
Stack<int> st1; // int
Stack<double> st2; // double
return 0;
}
2.了解什么是STL
STL这个名字相信大家在没接触过C++的时候就经常听到这个名字,可见它在C++中的重要程度。
网上常说,“不会STL,你不要说你会C++”,不言而喻,那接下来我们大体来了解一下什么是STL。
(1) 什么是STL
STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。
经过多年的迭代,STL有很多版本,我们主要学习的SGI版本。
(2)STL的六大组件
迭代器,容器,算法,仿函数,空间配置器,配接器
我们当前有所熟悉的就是容器这个概念,就是一些数据结构比如说栈,队列,二叉树等等,其他的我们在后续的学习中会一一介绍。
总结
今天我们步入了C++初阶的大门,C++这门语言终会被我们所掌握,料青山略输我峥嵘。