STL源码剖析笔记

并行和并发的区别?系统支持处理多个任务,就是并发;如果操作系统有多核,也即能支持同一物理时间上多个任务同时运行,则为并行。并行是并发的子集,区别在与是否多处理器。

C++14/C++17并发机制的更新?
在这里插入图片描述

1章 STL概论与版本简介

  1. STL是79年诞生,98年加入cpp标准库。C11出来之前boost库是常见的智能指针库,c11有自己的智能指针。且有多个STL版本,如SGI STL,GNU STL。
  2. p19-p34,用判断各种宏定义是否存在,来define一些变量,就是可以在不同的平台上,有不同的源码定义的意思。

2章 空间配置器

  • STL标准是要定义std::allocator,但SGI里面常用的确是std::alloc配置器p47。
    • SGI STL具有次级SGI空间配置器的能力,比如vector<int, std::alloc> iv写法。
    • SGI定义了一个simple_alloc类【用alloc实现】,用于实现vector等等数据结构。

STL 主要的内存配置器

SGI定义了一个simple_alloc类【用std::alloc实现】,用于实现两层配置器。p54、p55图展现关系、

  • 主配置器:在申请大内存时使用。底层用malloc和free实现。set_new_handller()函数可以定义一个在oom时的
  • 次配置器:如果申请小于128的内存则用此配置器。通过维护1个free-list,list含有16个块,每个块是一个链表,链表中还有块时就用,链表中块不够时去内存池memory pool取出一个块,供调用者使用。
    在这里插入图片描述
    在这里插入图片描述

内存池p66:就是free-list中chunk_alloc的实现。
chunk_alloc(size_t blockSize, int& requestNumberOfBlock)

  • 内存池能满足要求 requestNumberOfBlock * blockSize,就返回
  • 内存池能够满足一个 requestNumberOfBlock,就返回1个快
  • 1个内存快都不能满足:首先先将内存池中残余内存放入free_list合适的块中,在向heap申请内存补充内存池。

内存基本处理函数

以下3个类型,对pod类型数据会执行较快的拷贝如(copy/fill/fill_n),非pod类型执行for遍历一个一个拷贝。p76

  • uninitialized_copy:对初始化的区域,用拷贝构造来生成对象
  • uininitialized_fill
  • uininitialized_fill_n:对[Ft, Ft+n)

3章 迭代器概念与traits编程技法

STL设计容器&算法的思想

  1. 容器设计者:不仅要设计容器,还要尽可能基于iterator设计容器的5个typedef p84/89。
  2. deque_iterator虽然没有显示继承iterator实现,但它也实现了5个typedefp140。
  3. 算法设计者:设计对不同读写能力迭代器的算法。STL算法的命名以其能接受的最低层次的迭代器命名,如advance(InputIterator& i, Distance n)可以接受Input、Forward、Bidirectional、Random Access四种类型的参数。
    a. 总共是有input、ouput、forward、bidirectional、randomAccessIterator
    b. 支持随机读写的容器:vector,deque,
    c. 不支持随机读写的容器:list(底层链表)、pair(就两个元素)、map和set(红黑树或哈希表)
template<class Category, class T, class Distance=ptrdiff_t, 
        class Pointer=T*, class Reference=T&>
struct iterator{                                // 相当于java的interface。
    typedef Category  iteator_category;
    typedef T         value_type;
    typedef Distance  difference_type;
    typedef Pointer   pointer;
    typedef Reference reference;
}


// 某一个实现类应该是, 参考p100
template<class Item>
struct ListIter: public std::iterator<std::forward_iterator_tag, Item>{}

Traits获取变量类型

  • iterator_traits:负责萃取迭代器的各种类型
    • __type_traits:负责萃取pod相关的类型,p104
      无法复制加载中的内容
template <class I>
struct iterator_traits{
    typedef typename I::iterator_category iterator_category; // 帮助容器选择算法的
// func( iterator_traits<INPUT>::iterator_category());  // p99

    typedef typename I::value_type value_type;
    typedef typename I::difference_type difference_type;
    typedef typename I::pointer pointer;
    typedef typename I::reference reference;
}

如果没有反射,那怎么获取某个迭代器的类型呢?特性萃取iterator_traits。怎么获取某对象的类型呢?

type_traits。
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc> { // 有删减
  typedef _Tp                                         value_type;
  typedef typename _Base::pointer                    pointer;
  typedef typename _Alloc_traits::reference          reference;
  typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
  typedef size_t                                         size_type;
  typedef ptrdiff_t                                      difference_type;
}

4章 序列式容器

在这里插入图片描述

项目Value
电脑$1600
手机$12
导管$1
容器结构结构说明说明反正大家都是用simpe_alloc分配和释放的,具体是啥得看结构。insert()、insert_aux(iter, x)、erase、operatoer[]、
vector本质:用simple_alloc分配和释放的heap:用vector实现的堆,默认priority_queue:用vector【可以调整的】实现的优先级队列
listlist本质:带有哨兵的双向链表
dequedeque(双端队列)本质:利用复杂的map中控结构来管理,还可以随机读写的一个容器。双向开口的,所以头尾插入效率较高可随机读写的,random access关于deque的排序先赋值给vector,在用vector排序,这样效率高p143;stack本质:是用deque/list管理的先入后出的栈 queue本质:用deque/list管理的先入先出队列
slist本质:是一个只能头部插入(头插法的)单向的链表slist和list底层都是链表,其迭代器不是通过计算偏移量得到的故而不失效。比如list的insert, erase,splice,p186。slist一直头插法,insert、splice当然不失效;迭代器失效的情况:比如vector的insert会失效的。

在这里插入图片描述

5章 关联式容器

就是形如key:value的容器,比如map和set,通常以rb-tree为底层的,或者以hashtable为底层。
在这里插入图片描述

二分搜索树:特例有平衡的二分搜索树

  • 它的特例是AVL,相差为1
  • 红黑树,
    项目 | Value
    -------- | -----
#include 以红黑树RB-tree为底层的容器,就是node(key+value)为节点构建的树。插入就会增加节点,删除就会减少节点,有插入删除就会有RB-Tree的旋转过程。如果允许重复键值的插入:就有multiset、multimap;如果不允许重复键值的插入:就是map、set两个而已,p198-246,就总结出这么点点的东西。
#include <unordered_map>以hashtable为底层的容器,就是以桶和链表组成的表嘛。使用它就会有一些注意。如果一个插入操作让hashtable里元素个数>桶的个数,就会发生resize。桶的个数取值是比较固定的比如53、97、193等p257页有,每次取最接近的,且大于table元素个数的那个数。重要方法:insert_unique()方法插入唯一值,insert_equal方法插入可重复值。hash_function:很多对象不能hash,要自定义hash。自定义的类要自己写hash_funcEqualKey = eqaul_to:常见种类:hash_set、hash_map、hash_multiset、hash_multimap。
// #include <unordered_map>
// GCC的源码

template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
          class Alloc = allocator<pair<const Key, T>>>
class unordered_map
{
public:
    // types
    typedef Key                        key_type;
    typedef T                      mapped_type;
    typedef Hash                                 hasher;
    typedef Pred                                     key_equal;
    typedef Alloc                                     allocator_type;
    typedef pair<const key_type, mapped_type>                     value_type;
    typedef value_type&                                    reference;
    typedef const value_type&                               const_reference;
    typedef typename allocator_traits<allocator_type>::pointer       pointer;
    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
    typedef typename allocator_traits<allocator_type>::size_type       size_type;
    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
    
}
侯捷的《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、付费专栏及课程。

余额充值