标准库、容器和迭代器概述

这几天大概了解了一下标准库里面的函数都是哪些方面的,然后去医院照顾奶奶了几天。期间看了容器和迭代器相关。



标准库的概述

大概有这么几种组件:字符串、正则表达式、IO流、智能指针、异常、数学工具、时间工具、随机数、初始化列表、pair和tuple、optional、variant和any、函数对象、文件系统、多线程、类型特质、标准整数类型、容器、算法。

但同时标准库还有一些不支持的内容:多线程访问容器不能保证线程安全、没有提供泛型的树、图结构。

但是可以编写兼容标准库的代码,来扩展它。

容器和迭代器

容器是泛型数据结构,适合保存数据集合。(不用再像去年那样手写链表了)。除了array和bitset外,大部分标准库容器的大小灵活可变。

16种容器,四大类:

  • 顺序容器:
    • vector(动态数组)
    • deque
    • list
    • forward_list
    • array
  • 关联容器:
    • map
    • multimap
    • set
    • multiset
  • 无序关联容器或哈希表:
    • unordered_map
    • unordered_multimap
    • unordered_set
    • unordered_multiset
  • 容器适配器:
    • queue
    • priority_queue
    • stack

对元素的要求

标准库容器对元素使用值语义(value semantic)。也就是,在输入元素时保存元素的一份副本。通过赋值运算符给元素赋值,通过析构函数销毁元素。所以,在编写适用于标准库的类时,一定要保证它们是可以复制的。请求容器中的元素时,会返回所存副本的引用。

如果喜欢引用语义,可以存储元素的指针,而非元素本身。当容器复制指针时,仍然指向同一元素。另一种方式是在容器中存储std::reference_wrapper。可使用std::ref()或std::cref()来创建reference_wrapper,使引用变得可以复制。其相关函数和类模板在functional头文件中。

​ 容器中,可能存储“仅移动”类型。这是非可复制类型,这样做是,编译器可能报错。std::unique_ptr是仅移动的例子。

在容器内保存指针应该使用unique_ptr或shared_ptr。

​ 标准库容器的一个模板类型参数是分配器(allocator)。标准库容器可使用分配器为元素分配或释放内存。分配器类型参数具有默认值,因此几乎总是可以忽略它。

有一些容器(如map)也可将比较器(comparator)作为模板类型参数。比较器用于排序元素,具有默认值,一般不需要指定。

实现元素的移动语义可以提高性能(要标记noexcept)

异常和错误检查

标准库容器提供了非常有限的错误检查功能。客户应确保使用正确。

迭代器

标准库通过迭代器模式提供了访问容器元素的泛型抽象。每个容器都提供了容器特定的迭代器,迭代器实际上是增强版的智能指针,这种指针知道如何遍历特定容器的元素。所有不同容器的迭代器都遵循C++标准中定义的特定接口。因此, 即使容器提供不同的功能,访问容器元素的代码也可以使用迭代器的统一接口。

所有迭代器都必须可通过复制来构建、赋值、并且可以析构。左值可以交换。C++标准提供了5大迭代器:

输入迭代器

operator++,operator*,operator->,复制构造函数,operator=,operator==,operator!=。

提供只读访问,只能前向访问(没有operator--提供的后向访问功能)。这个迭代器可以赋值和复制,可以比较判等。

输出迭代器(“写”迭代器)

operator++,operator*,复制构造函数,operator=

提供只写访问,只能前向访问。这个迭代器只能赋值,不能判等比较。

输出迭代器特有操作*iter = value

(此类迭代器缺少operator->,但提供前缀和后缀operator++)

前向迭代器

输入迭代器的功能,加上默认构造函数。

提供读写访问,只能前向访问。可以赋值、复制、比较判等。

双向迭代器

前向迭代器的功能+operator--

提供前缀和后缀operator--

随机访问迭代器

双向迭代器的功能+ operator+ ,-,+=,-+,<,>,<=,>=,[]

等同于普通指针;此类迭代器支持指针运算、数组索引语法以及所有形式的比较。

同时,满足输出迭代器要求的迭代器称为“可变迭代器”,否则不变迭代器。

可以用std::distance来计算容器的两个迭代器之间的距离。

(迭代器类似于智能指针,因为他们都重载了特定的运算符)

posted @ 2020-05-06 16:28  LeoRanbom  阅读(316)  评论(0编辑  收藏  举报