博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STL源码阅读(四)
阅读量:6516 次
发布时间:2019-06-24

本文共 4541 字,大约阅读时间需要 15 分钟。

STL源码阅读(四) (SGI STL v3.3)

stl_deque.h (<deque>)

// deque的内存管理,分配一段内存_M_map用来存储指向缓存区域的指针,每当缓存区域buffer不足时,分配一段新的缓存区域,然后// 将指向该区域的指针添加到_M_map中。buffer大小的分配原则是,当sizeof(_Tp) > 512时,分配的缓存大小sizeof(_Tp);否则,// 分配的缓存大小为sizeof(_Tp) * (512 / sizeof(_Tp));template 
class _Deque_alloc_base; // 每个类中保留两个分配器对象,_M_map_allocator, _M_node_allocatortemplate
class _Deque_alloc_base<_Tp, _Alloc, true>; // 使用静态内存分配器 {... _Tp** _M_map; // 指向缓存结点的指针 size_T _M_map_size; // map的大小...}
// deque迭代器,迭代器类型随机迭代器random_access_iterator_tag。template 
struct _Deque_iterator {... // 迭代器中维护四个指针 _Tp* _M_cur; // 指向当前缓存区域已用空间的最后一个元素 _Tp* _M_first; // 指向当前缓存区域的开始 _Tp* _M_last; // 指向当前缓存区域的末尾 _Map_pointer _M_node; // 指向当前正在使用的那一个缓存区域...}// 注意迭代器迭代元素的方式,迭代器所处理的内存空间从整体上看不是连续的,但从局部看是连续的// 计算迭代器的差值difference_type operator-(const _Self& __x) const { return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) + (_M_cur - _M_first) + (__x._M_last - __x._M_cur);}_Self& operator+=(difference_type __n){ difference_type __offset = __n + (_M_cur - _M_first); if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) _M_cur += __n; else { difference_type __node_offset = __offset > 0 ? __offset / difference_type(_S_buffer_size()) : -difference_type((-__offset - 1) / _S_buffer_size()) - 1; _M_set_node(_M_node + __node_offset); _M_cur = _M_first + (__offset - __node_offset * difference_type(_S_buffer_size())); } return *this;}// deque基类template
class _Deque_base : public _Deque_alloc_base<_Tp,_Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> { ... typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; // 除了从_Deque_alloc_base继承过来的数据成员,还维护两个迭代器,分别指向元素的首部和尾部 iterator _M_first; // 指向第一个元素 iterator _M_finish; // 指向最后一个元素的下一个元素 enum { _S_initial_map_size = 8 }; // _M_map的初始大小为8 ... }// 初始化__num_elements个节点,最小结点数8个template
void_Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements){ size_t __num_nodes = __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2); _M_map = _M_allocate_map(_M_map_size); // 当多分配两个结点 // 指向_M_map的最中间,向头部和尾部的扩展能力相同 _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2; _Tp** __nfinish = __nstart + __num_nodes; __STL_TRY { _M_create_nodes(__nstart, __nfinish); // 为每个结点分配内存 } __STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size), _M_map = 0, _M_map_size = 0)); _M_start._M_set_node(__nstart); _M_finish._M_set_node(__nfinish - 1); _M_start._M_cur = _M_start._M_first; _M_finish._M_cur = _M_finish._M_first + __num_elements % __deque_buf_size(sizeof(_Tp));}
template 
class deque : protected _Deque_base<_Tp, _Alloc>;// 注意swap的实现void swap(deque& __x) { __STD::swap(_M_start, __x._M_start); __STD::swap(_M_finish, __x._M_finish); __STD::swap(_M_map, __x._M_map); __STD::swap(_M_map_size, __x._M_map_size);}// 当push_front, push_back, insert, resize添加元素超出原空间时,需要// 重新分配空间map,将原来的_M_map拷贝到新map中,并没有copy缓冲区的元素template
void deque<_Tp,_Alloc>::_M_reallocate_map(size_type __nodes_to_add, bool __add_at_front){ size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1; size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; _Map_pointer __new_nstart; if (_M_map_size > 2 * __new_num_nodes) { __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 + (__add_at_front ? __nodes_to_add : 0); if (__new_nstart < _M_start._M_node) copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); else copy_backward(_M_start._M_node, _M_finish._M_node + 1, __new_nstart + __old_num_nodes); } else { size_type __new_map_size = _M_map_size + max(_M_map_size, __nodes_to_add) + 2; _Map_pointer __new_map = _M_allocate_map(__new_map_size); __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + (__add_at_front ? __nodes_to_add : 0); copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); _M_deallocate_map(_M_map, _M_map_size); _M_map = __new_map; _M_map_size = __new_map_size; } _M_start._M_set_node(__new_nstart); _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);}

参考资料

转载于:https://www.cnblogs.com/corfox/p/6063305.html

你可能感兴趣的文章
Nginx介绍
查看>>
windows 配置dhcp服务器
查看>>
调整数组使奇数全部都位于偶数前面
查看>>
HYSwitch - iOS7风格的开关控件
查看>>
我的信念
查看>>
Java学习笔记(1)
查看>>
我的友情链接
查看>>
c++类模板深度剖析
查看>>
Xshell远程连接VMware如何修改网卡配置文件
查看>>
/proc/sys/net/ipv4详解(1)
查看>>
rpm命令浅析
查看>>
第一篇博文
查看>>
Windows SQL2008数据库系列一数据的导入导出
查看>>
web应用程序资源作用顺序测试报告
查看>>
华为以太网基础(二)
查看>>
制作VBS病毒文件
查看>>
filebeat 6.0以后版本设置index名字
查看>>
关于虚函数
查看>>
Oracle 11g R2在CentOS 5.5服务器上的安装(中)
查看>>
我的友情链接
查看>>