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的简单介绍 大家有一个印象就好 我们后面会具体学习


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


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


阿尼亚 哇酷哇酷!

相关文章
|
7天前
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
15 1
|
19天前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
33 7
|
2月前
|
存储 编译器 C语言
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
66 4
|
2月前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
81 5
|
2月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
63 2
|
2月前
|
安全 编译器 C++
【C++11】可变模板参数详解
本文详细介绍了C++11引入的可变模板参数,这是一种允许模板接受任意数量和类型参数的强大工具。文章从基本概念入手,讲解了可变模板参数的语法、参数包的展开方法,以及如何结合递归调用、折叠表达式等技术实现高效编程。通过具体示例,如打印任意数量参数、类型安全的`printf`替代方案等,展示了其在实际开发中的应用。最后,文章讨论了性能优化策略和常见问题,帮助读者更好地理解和使用这一高级C++特性。
63 4
|
2月前
|
算法 编译器 C++
【C++】模板详细讲解(含反向迭代器)
C++模板是泛型编程的核心,允许编写与类型无关的代码,提高代码复用性和灵活性。模板分为函数模板和类模板,支持隐式和显式实例化,以及特化(全特化和偏特化)。C++标准库广泛使用模板,如容器、迭代器、算法和函数对象等,以支持高效、灵活的编程。反向迭代器通过对正向迭代器的封装,实现了逆序遍历的功能。
37 3
|
2月前
|
存储 算法 Linux
【c++】STL简介
本文介绍了C++标准模板库(STL)的基本概念、组成部分及学习方法,强调了STL在提高编程效率和代码复用性方面的重要性。文章详细解析了STL的六大组件:容器、算法、迭代器、仿函数、配接器和空间配置器,并提出了学习STL的三个层次,旨在帮助读者深入理解和掌握STL。
61 0
|
22天前
|
存储 编译器 C语言
【c++丨STL】vector模拟实现
本文深入探讨了 `vector` 的底层实现原理,并尝试模拟实现其结构及常用接口。首先介绍了 `vector` 的底层是动态顺序表,使用三个迭代器(指针)来维护数组,分别为 `start`、`finish` 和 `end_of_storage`。接着详细讲解了如何实现 `vector` 的各种构造函数、析构函数、容量接口、迭代器接口、插入和删除操作等。最后提供了完整的模拟实现代码,帮助读者更好地理解和掌握 `vector` 的实现细节。
30 0
|
2月前
|
编译器 C++
【c++】模板详解(1)
本文介绍了C++中的模板概念,包括函数模板和类模板,强调了模板作为泛型编程基础的重要性。函数模板允许创建类型无关的函数,类模板则能根据不同的类型生成不同的类。文章通过具体示例详细解释了模板的定义、实例化及匹配原则,帮助读者理解模板机制,为学习STL打下基础。
33 0