[侯捷]C++体系结构与内核分析笔记

看视频记录的超简单的笔记以及一些C++资料,为了以后复习mark一下
[侯捷]C++体系结构与内核分析
大佬的C++那些事儿

STL六大部件

容器(Containers)

顺序容器:Array、Vector、Deque、List、Forward_list

关联容器:Set/Multiset、Map/Mulitimap

不定序容器:Unordered Set/Multiset、Unordered Map/Multimap

分配器(Allocators):class template
算法(Algorithms):function template
迭代器(Iterators):class template
适配器(Adapters):class template
仿函式(Functors):class template

一、allocators

1、前言

malloc分配出来的内存块长这样:
在这里插入图片描述

上下两个红块是这个块的边界,因为有这样一个边界,还内存的时候才可以只传递一个指针。正是因为有这么多的额外开销,所以malloc的开销很大。

2、正文

模板类里面主要是有一个allocatedeallocate方法(以下是VC6里的源码样子,和BC5、G2.9里实现的大致差不多)

allocate负责分配内存,传入两个参数:要分配多大的空间,类型为size_type和随便什么参数,类型为const void*,没有参数名。最终调用的还是operator new()方法(归根结底是malloc())。

deallocate负责释放内存,传入两个参数:内存首地址和内存空间大小。最终调用的是operator delete()方法(归根结底是free())。

使用示例:

//分配 512 ints.
int *p = allocator<int>().allocate(512, (int*)0);
allocator<int>().deallocate(p, 512)

但G2.9里的容器使用的其实是另一个更好的分配器alloc,能够减少malloc的次数。
在这里插入图片描述

然而,G4.9默认使用的又变成了std::allocator,设计跟VC、BC类似。同时,G4.9所附的标准库,有许多extention allocators,其中__pool_alloc就是G2.9的alloc

二、containers和iterators

目标:

(1)了解每种容器内部是如何实现的。

(2)了解每种容器的迭代器是如何移动的。
在这里插入图片描述

下图中的缩排表示“基层与衍生层”的关系。所谓衍生,并非继承而是复合。
在这里插入图片描述

只要是号称是连续空间的容器,都有operator[]操作

1、list

list是一个双向链表,每个结点有两个pointer和一个data。因为list内存空间不连续,所以它的iterator必须得是一个类,才能重载++运算符。

Iterator必须为algorithm提供5种associate types
1)iterator_category
2)value_type
3)difference_type
4)reference
5)pointer

iterator是指针类型时,iterator无法直接回答algorithm上述的五个问题,因此引入一个中间层iterator traits,再偏特化就能代替iterator回答algorithm的五个问题。

2、vector

vector内有三个指针:startfinishend_of_storagevector的内存增长是两倍增长。

因为vector内存空间连续,所以它的iterator就是一个指向vector元素的指针。

3、array

array不能扩充,定义变量时需要指定大小。

4、forward_list

5、deque

deque分段连续,为了维持连续的假象,当iterator走到一个buffer的末端时要能力跳到下一个buffer的起始点。

在这里插入图片描述

6、rb_tree
在这里插入图片描述

红黑树是一种自平衡二叉查找树,内有iterator,一直进行++iterator操作会得到一个有序序列。

不能通过iterator修改树结点值,因为修改后树可能就不是有序的,且红黑树是mapset的底层实现,而map的键值是不能被修改的。

实现用例:

在这里插入图片描述

7、set/multiset

set的大部分操作都是由其内含的红黑树完成的,set里的iterator是红黑树的const_iterator(不能修改值)。

8、map/multimap

map以红黑树为底层结构,因此也有元素自动排序的特性,排序的依据是key

map元素的key必须独一无二,因此其insert()用的是rb_treeinsert_unique()

multimap元素的key可以重复,因此其insert()用的是rb_treeinsert_equal()

map独有一个operator[],可以做插入操作。

9、hashtable

可以根据hashtable iterators改变元素的data,但不能改变元素的key(因为hashtable根据key实现严谨的元素排列)。

在这里插入图片描述

10、unordered

unordered_set
unordered_multiset
unordered_map
unordered_multimap

三、algorithms

Algorithms看不见Containers,对其一无所知,所以它所需要的一切信息都必须从Iterators取得,而Iterators(由Containers供应)必须能够回答Algorithm的所有提问,才能搭配该Algorithm的所有操作。

//五种iterator category
struct input_iterator_tag{
   };
struct output_iterator_tag{
   };
struct forward_iterator_tag:public input_iterator_tag{
   };
struct bidirectional_iterator_tag:public forward_iterator_tag{
   };
struct random_access_iterator_tag:public bidirectional_iterator_tag{
   };

算法需要知道迭代器的种类,好根据不同的类别采用不同的方法对迭代器进行操作,以提高程序效率。

1、accumulate

template <class InputIterator, class T, class BinaryOperation>
T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op){
   
    for(;first != last;++first){
   
        // 传进来的binary_op只要能进行()操作就可以(意味着函数,仿函数等都可以)。
        init = binary_op(init, *first);
    }
    return init;
}

2、for_each

template <class 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值