《STL源码剖析》 笔记

  • 实在有点难读下去,第一次读就读得比较粗糙了。

第1章 概论与版本简介

  • 为建立数据结构和算法的一套标准,并且降低其间的耦合关系,以提升各自的独立性、弹性、交互操作性,C++社群里诞生了STL。
  • STL是一个抽象概念库,这些抽象概念包括:
    ①最基础的:可被赋值、不需要任何参数就可构造、可判断是否相同、可比较大小、正规。
    ②高阶一点的:具输入功能的迭代器、具输出功能的迭代器、单向迭代器、双向迭代器、随机存取迭代器、一元函数、二元函数、传回真假值的一元判别式、传回真假值的二元判别式。
    ③更高阶的:序列式容器、关联式容器。

 

  • STL的六大组件

    ①容器(containers):各种数据结构,如vector、list、deque、map等。实现上看是一种class template。

    ②算法(algorithms):各种常用算法,如sort、search、copy等。实现上看是一种function template。

    ③迭代器(iterators):容器与算法之间的胶合剂,一种“泛型指针”。将*、->、++、--等指针相关操作重载的class template。所有STL容器都附带有自己专属的迭代器。

    ④仿函数(functors):行为类似于函数,可以作为算法的某种策略。

    ⑤配接器(adapters):一种用来修饰容器或仿函数或迭代器接口的东西。像queue、stack,看起来像容器,其实只是一种容器配接器。

    ⑥配置器(allocators):负责空间配置与管理。一个实现了动态空间配置、空间管理、空间释放的class template。

 

  • 由于STL已成为C++标准程序库的大脉系,所以目前所以的C++编译器一定有一份STL。
  • STL并非以编译好的二进制代码出现,而是以源代码提供给用户。
  • 因为C++标准规定,所以标准头文件不再有扩展名。但某些STL版本同时具有扩展名和无扩展名两份文件(可能是为了向下兼容、或者内部组织管理)。

 

  • 任何一个STL算法,都需要获得由一对迭代器标示的区间,来表示操作的范围。而这个区间是[first,last)表示。也就是说实际范围是从first开始,到last-1结束。
  • 在C时代,要将函数当参数传递,只能通过函数指针。但函数指针有缺点,它无法拥有自己的“状态”,也就是说没法再次将一些修饰条件加于其上、改变其状态。
  • 为此,STL算法接受所谓的“策略”或“一组操作”,以仿函数的形式呈现。
  • 仿函数:使用起来和函数一样,如果针对某个class进行operator()重载【即重载()符号】,它就成为一个仿函数。
#include<iostream>
using namespace std;

//将operator()重载,使plus成为一个仿函数
template<class T>
struct plus{
	T operator()(const T& x, const T& y)const { return x + y; }
};

int main() {
	//产生一个仿函数对象
	plus<int> test;
	//使用仿函数,就和使用普通函数一样
	cout << test(3, 5) << endl;

	//也可以产生一个临时对象,并且调用
	cout << plus<int>()(3, 5) << endl;

	getchar();
	return 0;
}

 

第2章 空间配置器(allocator)

  • 叫做空间配置器,而不是内存配置器。因为除了内存,空间还是可以是磁盘或者其他存储介质。
  • 为精密分工,STL allocator将对象构造析构内存分配释放两个阶段操作区分开(new delete时是合并的)。
  • 内存配置操作:alloc::allocate()
    内存释放操作:alloc::deallocate()
    对象构造操作:::construct()
    对象析构操作:::destroy()

 

第3章 迭代器

  • 迭代器是一种行为类指针的对象。迭代器最重要的编程工作就是对operator*和operator->重载。

 

第4章 序列式容器

  • 依据“数据在容器中的排列”特性,容器的数据结构分为序列式(sequence)和关联式(associative)两种。
  • 序列式容器:array(C++内建)、vector、heap(以算法形式呈现xxx_heap)、priority-queue、list、slist、deque、stack(配接器)、queue(配接器)。
  • heap内含一个vector,priority-queue内含一个heap,stack和queue都内含一个deque。
  • 关联式容器:RB-tree(非公开,衍生出后面几种):set、map、multiset、multimap。(后面的是非标准)hashtable、hash_set、hash_map、hash_multiset、hash_multimap。

 

  • vector和array的区别在于vector空间运用的灵活性。array是静态空间,一旦配置了就不能改变。而vector是动态空间,随着新元素加入,内部机制会自动扩充空间。
  • vector采用的是:线性连续空间。内部以start和finish两个迭代器来指向配置得来的连续空间中,目前已使用的范围;以迭代器end_of_storage指向整块空间的尾端。
  • 按照书中说法,vector每当遇到空间不足的时候,会以2倍增长,也就是说:2→4→8→16等等。但在VS中实际测试的数据却是:2→3→4→6→9→13→19→28→42,整体计算是以1.5倍的速度增长。然后我就又进了gcc去看,确实是2倍速率增长的。

    为啥是1.5和2呢?显然,增长的倍数不可能很大,也不会比 1 小,那么,它的最佳上限是多少呢?如果以 大于2 倍的方式扩容,下一次申请的内存会大于之前分配内存的总和,导致之前分配的内存不能再被使用。所以,最好的增长因子在 (1,2)之间。然后好像有谁实验证明1.5是最佳值,就有了1.5,具体怎么证明就不太清楚了,大概知道就好。
  • vector可能存在旧空间不足,后面也没有合适的空间,于是会重新配置一块更大的空间,然后复制元素,再释放旧空间。

 

  • list结点的结构体:
template <class T>
struct __list_node{
    typedef void* void_pointer;
    void_pointer prev;
    void_pointer next;
    T data;
}
  • list的插入操作和结合操作,都不会造成原有的list迭代器失效,而在vector中是会的。

 

  • deque和vector差异:①deque可以在常数时间内对头端进行元素的插入或移除。②deque没有所谓的容量概念,因为它是动态地以分段连续空间组合而成。
  • deque采用了一块所谓的map(不是STL的map)来实现。这里的map是一小块连续空间,其中每个结点都是一个指针,指向另一段较大的连续线性空间,也就真正的存储主体,称为缓冲区。一旦map所提供的结点不足,会重新分配一块更大的map。

 

  • stack和queue的内部都是默认以deque实现的。同样,stack和queue都没有迭代器。

 

第5章 关联式容器

  • 标准STL关联式容器为set和map两大类。这两大类的衍生体有multiset和multimap。这些容器的底层机制均以RB-tree红黑树实现。RB-tree也是一个独立的容器,但不开放给外界使用。

  • set和map不一样之处是,map有实值value和键值key,而set只有一个值,并且不允许两个元素有相同的键值。set中所有元素都会根据元素键值自动被排序。
  • map会根据元素的键值自动排序。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
侯捷的《STL源码剖析》是一本关于STL(标准模板库)的学习笔记。这本书深入解析了STL的实现原理和设计思路,对于理解STL的内部机制和使用方法非常有帮助。这些学习笔记记录了作者在学习侯捷的《STL标准库和泛型编程》课程时的心得和总结,对于理解STL源码和进行泛型编程都具有指导意义。 这本书涉及了STL的各个模块,包括容器、迭代器、算法等,并解释了它们的实现原理和使用方法。通过学习这本书,你可以更好地理解STL的底层实现和使用技巧。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [STLSourceAnalysis:stl原始码剖析(侯捷)的学习笔记](https://download.csdn.net/download/weixin_42175776/16069622)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [候捷老师STL源码剖析视频课程笔记](https://blog.csdn.net/weixin_46065476/article/details/125547869)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [侯捷——STL源码剖析 笔记](https://blog.csdn.net/weixin_45067603/article/details/122770539)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值