侯捷——STL源码剖析 笔记

第一部分 Sequence containers序列式容器

序列式容器

for(auto ch:s)//虽然用了auto,但auto到底应该是什么应该心里有数

1、容器分类与测试

侯捷:

  1. 在我要用到定义的时候,才去在函数之前定义他而不是全部集中在开头。

  2. 测试单元分开放。

namespace jj06{
int a;
int func(){
}
}

最好不要用分配器allocator,少量取内存可以用new搭配delete。

9

OOP是将data与method放一起,GP是分开放。

13 list

在C++中,规定了带有参数的是后置++,没有参数的是前置++,没有意义,只是区分之用。

前++,后++,int前++可以加两次,用的是reference&,后++不可以加两次,返回的是值。

list的继承关系较为复杂,父类大小多少,子类也是多少。

15 traits 萃取出特性

算法向iterator提出的问题,有些iterator不是class,是退化的(c++原始的指针),需要traits来提取分辨,再交给算法。

16 vector深入探索

没有空间扩大空间的时候,先是找一块连续的原来两倍大的空间,然后将原来的和新加入的元素移过去。安插点之后的元素也要拷贝过去,因为可能是insert调用此扩大函数。

所以每次扩大空间的时候会耗费很多资源。

泛化,偏特化

traits接收的五个问题,五个变量会经过很复杂的名词定义转变给到traits。

17 array,forward_list探索

array,没有构造,析构函数,vector和array都是连续空间,所以iterator都是原始指针,不是class。

forwardlist是单项链表,和list类似,list是双向的。

18-19 deque

deque是双向开口的,vector是单向开口的。控制中心是一个vector。旧版deque可以指定缓冲区大小,新版不可以。deque对外声称是连续的,虽然他不是连续的。insert很巧妙,如果在块的前面位置insert,就移动前面的元素,如果在后面一点,就移动后面的元素。

用后++调用前++,用后–调用前–,知名库人都这么写。

此处有一个图

因为声称是连续的,所以有+=的操作,能一次移动一格以上,此时,判断是否跨越块,进行相应的移动。

queue stack

封掉deque的一些功能,就是queue和stack了,list也可以作为两者的底层结构,但是很可能更慢,stl不采用,stack可选择vector做为底层,queue不行。

两者都不能遍历,也没有iterator。两者都不可以选set或map做为底层。

做为底层结构dequelistvectorset、map
stack×
queue××

第二部分 associative - container关联容器

查找和插入非常快,相当于数据库,用一个key去找value。红黑树和散列表是常见的底层结构。

20 rb_tree红黑树

是平衡搜索树。begin永远记录最左边的节点。不应用迭代器去赋值,会破坏树的形式,这就是map的key,但是key对应的data可以改。红黑树并没有规定是否能放重复的key ,看你的需求。

为了符合handle and body柄体模式,所以在主体里没有多少操作的内容,而在外面另有一个implementation函数。

21 set、multiset

set是container adapter,操作都包给底层结构去做了,他自己不用做,有些人都不认为他们是一类容器。

如何禁止大家通过iterator修改key,可以设置iterator的类型为const_iterator。

identity函数,就是接受一个x,传回一个x,一致性。

22 map,multimap

operator[]里用了lower_bound二分搜索函数,如果找到了,返回元素,如果没有找到,返回最适合放元素的位置。

23-24 hashtable

哈希表,如果有碰撞,就放在这个桶(bucket)的链表里往后排(很多桶),但是链表太长也会造成查找不便。如果链表长度超过桶长度,就倍增,然后选择附近素数作为新的桶数。

按照计算,class作为成员不占空间,但是因为技术原因,还是占1个字节。

hashfunction hashcode hash_function是最重要的函数,用来将对象转化成一个数字放入table里排列,如果本身就是整型,返回自身即可,如果不是,有char的转换提供,没有的话自己可以写。

hashtable就是取余数放进对应篮子bucket。

25 以hashtable为基础的map,multimap,set,multiset

25的视频内容和23一样。。

26 unordered容器

set和map一般都用红黑树实现,因为性能好

map: map内部实现了一个红黑树,该结构具有自动排序的功能,因此map内部的所有元素都是有序的。
unordered_map: unordered_map内部实现了一个哈希表,因此其元素的排列顺序是杂乱的,无序的。

就是hash_set hash_map hash_multimap等的hash一词替换为unordered变为unordered_set,unordered_map等。

第三部分 算法

27 算法

算法看不到容器,只能通过迭代器进行运算。

28 迭代器的分类

前面6分钟和27一模一样。

iterator_category容器
forward单向前进。。
bidirectional双向前进
random随机访问下标

从下往上是继承关系。

仅仅继承一些typedef也有好处那就是减少重新抄写。

29 迭代器的分类对算法影响的实例

一个小技巧:临时对象,就是无名对象,

类型()

很简单就做出来了。

distance,advance

此函数计算两迭代器之间的距离。如果是random_access,可以直接相减;如果是input类型,需要一步步前进,计算距离。

advance类似,是前进或后退迭代器的函数。

copy,destroy

copy使用范围很广,可以将任一容器的任一段copy到任任地方。因为其用了很多泛化和特化,通过多次判断是否是普通指针还是容器,是否指向char等,来分化各种情况,达到最适合最快方案。其中有些方法用到了memmove(),一c语言函数,方便快捷。

什么算是不重要的,析构函数等是自动生成的,里面没有内容的,算是不重要的函数。

算法代码会暗示你传入什么类型的iterator,虽然都能接收,但是不合适的iterator算法可以选择不对其处理,算法特意修改模板参数名来暗示适应范围。

30 算法实例

function object(函数对象)也叫仿函数。

predicate:一种判断条件

自带的成员函数比标准库里的更快。

end()指的地方与rbegin()一样,但是取数方式稍微不同,所以需要套一个适配器adapter进行改造。

31 仿函数functor

六大部件里最简单的。

仿函数是一些额外的准则,来辅助实现算法,类似于sort里面cmp函数。

如果自己写仿函数,并希望以后能易于修改,被adapter改造,融入stl,需要继承一些给定的基类。

32 适配器

很多适配器。

  1. 函数适配器

  2. 容器适配器containers

  3. 迭代器适配器

一、容器适配器

stl提供两个queue和stack,他们修饰deque而成,通过选择性的封闭、开放一些接口形成。

二、函数适配器

bind2nd

到底是函数的调用,还是传入一个对象,c++里讲了很多次了,后面直接加一个小括号的,是创建了一个临时对象。

没听完,下课后再仔细听,学习

bind

占位符,可以用来代替参数

auto fn_hello=bind(hello,_1,2)//占位符为_1

三、迭代器适配器

reverse_iterator

没重点

inserter

copy函数本质上只能赋值,但是加入了inserter,可以进行插入操作,并且会自动扩容。

四、未知适配器

ostream

能适配ostream的适配器,通过重置copy函数里operator函数的方式,使operator里面定死的过程得到改变。

istream

。。

第四部分 stl周边技术与应用

40 一个万用的哈希算法

使用仿函数创建一个类。利用c++函数可变参数模板,设置三个同名参数(还能设置传入任意个参数),进行递归操作,最终算出一个hash code。

41 tuple

这是一个神奇的函数定义,

tuple<int,string,double> tup;

能组合任意类型,任意数量,为对象。

和上一个万能哈希函数比,这里也用了递归,是用继承父类实现递归。

42 type traits

带指针就一定要写析构函数

44 cout

如果是你自己的类型,需要你自己去重载<<,来cout。

45 moveable元素

深拷贝:欢迎欢迎,浅拷贝很危险,深拷贝不只是指针本身还有后面的都拷贝。

copy是深拷贝,move是浅拷贝,只交换3个指针。move版本有&&。

参考

t.csdn.cn
stl源码剖析笔记 写的挺好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值