C++ 模板初阶 初识STL

简介: C++ 模板初阶 初识STL

本章目标


模板


1.了解泛型编程

2.熟悉模板函数

3.熟悉类模板


STL初阶


4.了解什么是STL

5.了解STL版本

6.了解STL六大组件

7.了解如何学习STL

8.了解STL的缺陷


一. 模板


1.1 范型编程


这里要求我们写一个整型的交换函数 对于我们现在来说肯定是伸手就来了是吧


void swap(int& x, int& y)
{
  int tmp = x;
  x = y;
  y = tmp;
}
int main()
{
  int a = 10;
  int b = 20;
  swap(a, b);
  cout << a << endl;
  cout << b << endl;
  return 0;
}


0efab95ee4284ea695d3489d92cbcfa4.png

然后又开始提要求了 现在能不能写一个double类型的交换函数呢?


也很简单是吧 我们只需要将前面的代码复制一遍 然后转化下类型就可以是吧


那么接下来 字符类型呢? 指针类型呢?


他们之间是不是很相似 只需要改变结构数据类型就好了


但是我们每次都要拷贝一遍是不是很麻烦 所以说C++中就引入了一个泛型编程的概念


泛型编程:编写与类型无关的通用代码,是代码复用的一种手段,模板是泛型编程基础


1.2 函数模板


函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。


语法格式如下


我们这里使用typename或者class都是可以的


emplate<typename TP> // template<class TP>
void swap(TP& x, TP& y)
{
  TP tmp = x;
  x = y;
  y = tmp;
}
int main()
{
  int a = 10;
  int b = 20;
  swap(a, b);
  cout << a << endl;
  cout << b << endl;
  return 0;
}


这里不论我们使用整型字符型还是double类型都是可以交换的

bea96fd5306e4419b279c08d017d1d97.png


那我们可以说 这就是一个函数模板


那么问题来了 我们这两次调用的swap是同一个函数嘛?


很显然不是 因为我们这里连参数都不一样 所以肯定不是一个函数


那么我们调用的函数是从哪里来的呢?


我们在前面是不是说过我们写过的代码其实是一个函数模板啊


所以说我们下面调用的函数实际上是函数模板的实例化

c24f926b6a554209babf5210601bf1d3.png


下面介绍下函数模板的一些使用细则


如果前面已经定义了具体类型的参数

如果前面定义了具体类型的参数 那么后面就不会实例化了


我们来看看代码


132c736b02744569bb8115a9cd6a577d.png

假如我取消掉int的注释呢?


我们是不是就会发现


可以直接进入汇编代码了 不会出现二义性


f9a18a85f14940d1a5b8cf9282a29492.png

这就好比你如果家里做好了饭 是不是就不会出去吃外卖了啊


出现不同不同类型参数

7866346b4884446fb00684b982d92860.png


假设我们这里出现一个整型一个字符类型那么这里就会报错了!


为什么呢?


因为这里T一开始推导的是整形 但是后面却又变成字符形了 所以说这里会冲突


这里又两种方式可以解决


一种是类型强转

bb916795c14d4bc9bb64c5b8f8c66ccc.png


还有一种就是显示实例化


b5ee8df13e6a405a9999f6699d9c7130.png

还有一种方式就是我们多设置一个参数 (类似于函数就可以 )


aa3d47e1fbde4425ac192e43e6417e5a.png


1.3 类模板


类模板其实和函数模板类似


1.3.1为什么要有类模板


因为在我们实际写代码的过程中 我们使用的变量是会变化的


这个时候用int 下面可能就是用double了


有人可能要问了 我们使用typedef也可以改变啊


那为什么我们不继续使用typedef而使用类模板呢?


因为使用typedef有个致命的缺陷


就是在同一段函数内 我们只能使用一种数据类型


如果typedef是不是整个函数的所有类型都发生变化了啊


所以说这就是我们为什么要使用类模板的原因


1.3.2 类模板的定义格式

c0d6604fd8954f988e9b2e30bda87970.pngc0d6604fd8954f988e9b2e30bda87970.png

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类.


我们直接来看代码


template<typename T>
class Stack//注:此Stack类并不完美,但对于演示来说,Stack是否完美并不重要
{
public:
  Stack(int capacity = 4)
  {
    cout << "Stack(int capacity = )" <<capacity<<endl;
    _a = (T*)malloc(sizeof(T)*capacity);
    if (_a == nullptr)
    {
      perror("malloc fail");
      exit(-1);
    }
    _top = 0;
    _capacity = capacity;
  }
  void Push(const T& x)//对于这里引用来说,是最好的,因为如果x本身是类,传值就会调用拷贝构造,传引用有效的避免了这种情况
  {
    // ....
    // 扩容
    _a[_top++] = x;
  }
private:
  T* _a;
  int _top;
  int _capacity;
};
int main()
{
  Stack<int> st1;
  st1.Push(1);
  Stack<double> st2;
  st2.Push(2.1);
  return 0;
}


我们可以发现 在最后的时候 我们成功使用了两个类型不同的栈 (一个int 一个double)


如果我们不写显示类型的化就会报错

c0d6604fd8954f988e9b2e30bda87970.png



二. 初识STL


2.1 什么是STL?


STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。


记住STL分别是什么单词就好了


standard 标准


template 模板


libaray 库


2.2 STL的版本


这里有很多个版本 我们需要记住有两个 一个是初始的HP版本 它是由惠普实验室研发的


还有一个就是我们目前研究的版本 SGI版本


原始版本

Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP 版本–所有STL实现版本的始祖。

P. J. 版本

由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,符号命名比较怪异。

RW版本

由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。

SGI版本

由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。我们后面学习STL要阅读部分源代码,主要参考的就是这个版本。


2.3 STL的六大组件

5ca9a305211140858b22be93f262fadb.png


这里我们主要学习的是算法和容器 也即是一些排序交换 和一些基本的数据结构


2.4 如何学习STL


这里借用下 The C++ Standard Library作者的一段话

ff68f9b8f18d482f83f8cde292c4bfa8.png


总结下


我们目前就是要熟练使用STL


再之后了解STL原理 (第一阶段之后)


2.5 STL缺陷


总的来说无非那么几点通病


更新速度慢

追求效率 所以会稍微复杂点

自身有代码膨胀问题(其实就是模板语法导致的


总结


本文简单的介绍了模板的语法还有STL的简单介绍 大家有一个印象就好 我们后面会具体学习


由于作者水平有限 所以错误在所难免 希望大佬看到之后可以及时指正


如果说本文有帮助到你 别忘了 一键三连啊


阿尼亚 哇酷哇酷!

相关文章
|
1月前
|
存储 算法 C++
C++ STL 初探:打开标准模板库的大门
C++ STL 初探:打开标准模板库的大门
89 10
|
1月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
47 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
22天前
|
存储 程序员 C++
C++常用基础知识—STL库(2)
C++常用基础知识—STL库(2)
60 5
|
21天前
|
编译器 程序员 C++
【C++打怪之路Lv7】-- 模板初阶
【C++打怪之路Lv7】-- 模板初阶
13 1
|
22天前
|
存储 自然语言处理 程序员
C++常用基础知识—STL库(1)
C++常用基础知识—STL库(1)
44 1
|
1月前
|
算法 安全 Linux
【C++STL简介】——我与C++的不解之缘(八)
【C++STL简介】——我与C++的不解之缘(八)
|
1月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
51 5
|
1月前
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
37 0
C++入门6——模板(泛型编程、函数模板、类模板)
|
1月前
|
算法 编译器 C++
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
【C++篇】领略模板编程的进阶之美:参数巧思与编译的智慧
72 2
|
1月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
49 2