侯捷老师是个很有意思的人,虽然我对他课的期待最初来自于一些风言风语,说他吉他弹的非常好,然后听了几节课下来发现,竟然还挺有意思。我猜我对C++的兴趣,就源自那里吧。

##第一节课##

  • 函数名称就是函数地址
  • 编译器检查符号重载(operator override)时,向左看类型
  • typename后面加(),表示产生这个typename的临时对象
  • 编译器会对fuction template进行实参推导,所以不用<>来指定类型

##第二节课##

  • vector的iterator的类型为指针
  • 32位机器上指针为4 Byte,所以sizeof(vector)是3个指针大小 (start,finish,end\ of_storage)
  • 两个指针相加减,会根据类型自动算出元素的个数间隔而不是真正的地址相减
  • operation ++() 为前++,但是为了区分前后++,另外还有一个operation ++ (T)的操作符重载,表示后++
  • 关于 -> 操作符的重载,采取迭代措施,由编译器负责解决
  • 容器的iterator需要而且一定要定义五个type,分别为:
    • iterator_category
    • value_type
    • pointer
    • reference
    • difference_type
  • operator new是一个函数,在这个函数中调用了malloc (operator delete同理)
  • malloc分配区块大小时,会在区块的开头结尾加上cookie块,分别为4 Byte大小,保存了这个区块的大小信息。上面的cookie保存的信息可以用于free这个区块资源,下面的cookie用来合并区块
  • GNU的c++ STL不用标准的Allocator,而是用其自己实现的Alloc,Alloc分配器可以实现去掉cookie的作用,获得nocookie block
  • Alloc使用16个free list,大小从8 Byte到128 Byte递增,超过128 Byte的资源申请不使用Alloc来分配,直接用malloc(为何使用128这个数字,是开发人员考虑到浪费率的问题,认为128 Byte之后,cookie造成的浪费可以接受)
  • 比如:Alloc得到获取32 Byte的资源申请,那么它向操作系统申请40倍的32 Byte大小的区块(区块指针借用每个区块的前4个Byte,叫做embeded pointer),对前20块进行切割,每块32 Byte,给出第一块到用户,链接第二块地址到#4,后面20块不切割,作为储备,如果此时有一个64 Byte大小的申请,则将储备切割成10块64 Byte,给出第一块给用户,链接第二块到#7

##第三节课##

  • 本页第一行的三个模板参数的存在,是为了应对const型的iterator,更加灵活。

    1
    self tmp = *this
  • 调用了其构造函数,所以并不是类型转换错误

  • 如果malloc失败,则从最近的pool里面切一个出来应急
  • 所以alloc的free list模型获取block先要查看pool,如果pool足够切出相应大小的块,则直接切;若不够,产生了碎片,则先将碎片挂载到对应的list下面,然后重新想操作系统申请
  • GNU C++的alloc在进程死掉之前,不会将资源归还给操作系统,即未使用free函数,是一种霸占资源的方式
  • deque,双向队列,分段连续,所以对于使用者来说,就是连续的;map里面最初有8根指针,如果不够,则双倍扩张map大小
  • deque的insert操作将向元素少的那边推
  • malloc分配之后,其区块有上下两cookie,两个cookie内容完全一致,保存了区块的大小,由于大小是16的倍数,所以长度的最后四个bit都是0,而cookie就用其最后一个字节表示该区块十分被归还,这样的话就可以判断是否能够被合并
  • stack,queue都是用了Adapter设计模式复用了deque

##第四节课##

  • hashtable: 元素超过篮子的个数时,就rehash
  • _STL_TEMPLATE_NULL 在编译的时候会被转换成template<>,即模板的特化(template specialization)
  • hash_set是一种退化,key就是value,value就是key