当前位置: 首页 > news >正文

做权重网站crm免费永久使用

做权重网站,crm免费永久使用,wordpress禁止游客访问,wordpress小说站模版用了这么久的 vector #xff0c;今天终于有时间来看下STL的实现源码了#xff0c;开心?~最近几个月在刷 leetcode #xff0c;用的较多的数据结构就是STL里面的 vector 了#xff0c;相比较于直接的 array 数组#xff0c;它具备了灵活地根据需求去分配管理内存#xf… 用了这么久的 vector 今天终于有时间来看下STL的实现源码了开心?~最近几个月在刷 leetcode 用的较多的数据结构就是STL里面的 vector 了相比较于直接的 array 数组它具备了灵活地根据需求去分配管理内存用户只管往里面扔东西拿东西而不用费心费力去解决C里面的动态内存问题。那么大致猜想一下要实现一个这样的容器不难想出在 vector 中至少存在这样三个私有成员head(指向列表第一个元素位置), tail(指向列表最后一个元素位置), size(容器大小) 打开源码看看得到验证templatetypename _Tp, typename _Allocstruct _Vector_base {    ......    struct _Vector_impl_data {        pointer _M_start;  // 指向容器中的第一个元素是一个指针指针类型为 Tp 所示类型        pointer _M_finish; // 指向容器最后一个元素也是一个指针        pointer _M_end_of_storage; // 指向容器最后的位置        ......    }}templatetypename _Tp, typename _Alloc  std::allocator_tp class vector : protected _Vector_base_tp {typedef _Vector_base_tp _Base; // 如上 _Vector_base 所示是一个基础实现    ......public:typedef _Tp value_type;  // 数据类型typedef typename _Base::pointer pointer; // 全局数据指针    ......}总之就是一层套一层封装了一个又一个来完成对数据的抽象。但是最后的接口是放在 vector 上放开的。vector 支持动态内存分配支持随机存取访问因此在数据访问上具备了指针有的特性。那么它在源码上是怎么实现的呢首先来看它的接口(一部分常用接口)都有哪些**注**虽然包含 头文件就可以用 vector 但是它的实现源码其实是在 bits/stl_vector.h 下的而且下面的程序删掉了一些注释类、系统判断类函数。templatetypename _Tp, typename _Alloc  std::allocator_tp class vector : protected _Vector_base_tp {    ...// 获取指向第一个元素的指针    iterator begin() { return iterator(this-_M_impl._M_start); }// 获取指向容器最后一个可存放位置的下一个位置iterator end(){ return iterator(this-_M_impl._M_finish); }// 获取容器当前存放了多少元素size_type size() const { return size_type(this-_M_impl._M_finish - this-_M_impl._M_start);     }// 对容器进行重新分配大小void resize(size_type __new_size) {if (__new_size  size())            _M_default_append(__new_size - size());else if (__new_size             _M_erase_at_end(this-_M_impl._M_start  __new_size);    }// 获取容器自身大小size_type capacity() const  {return size_type(this-_M_impl._M_end_of_storage                         - this-_M_impl._M_start);    }// 看看容器当前是否为空bool empty() const  { return begin()  end(); }// 获取一个能够对返回对象读写操作的引用类型其实就是指针    reference operator[](size_type __n)  {return *(this-_M_impl._M_start  __n);    }protected:// 检查访问是否合法void _M_range_check(size_type __n) const {if (__n  this-size())            __throw_out_of_range_fmt(__N(vector::_M_range_check: __n (which is %zu)  this-size() (which is %zu)),                                     __n, this-size());    }public:// 跟 [] 操作符差不多只不过多了一层范围检查reference at(size_type __n) {        _M_range_check(__n);return (*this)[__n];    }// 获取能够对头部元素读写的指针reference front()  { return *begin(); }// 获取最后一个元素reference back()  { return *(end() - 1); }// 向容器末尾追加一个元素进来void push_back(value_type __x) { emplace_back(std::move(__x)); }templatetypename... _Args#if __cplusplus  201402L    reference#elsevoid#endif    emplace_back(_Args ... __args);// 将最后一个元素从容器中删掉void pop_back()  {        --this-_M_impl._M_finish;        _Alloc_traits::destroy(this-_M_impl, this-_M_impl._M_finish);    }// 在指定位置插入 n 个 __xiterator insert(const_iterator __position, size_type __n, const value_type __x) {        difference_type __offset  __position - cbegin();        _M_fill_insert(begin()  __offset, __n, __x);return begin()  __offset;    }// 擦除掉某一个位置上的元素iterator erase(const_iterator __position) { return _M_erase(begin()  (__position - cbegin()));     }// 交换两个容器中的东西void swap(vector __x)  {this-_M_impl._M_swap_data(__x._M_impl);        _Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),                                  __x._M_get_Tp_allocator());    }// 将容器内所有元素清空void clear()  { _M_erase_at_end(this-_M_impl._M_start); }};程序中大量出现的 allocator 是来自SGI STL的空间分配器说白了就是用来分配空间内存的。在拿到这部分源码后vector 的实现原理也就可以大致有所掌握了(毕竟每个接口也不过几行?这可能就是优秀设计的结果?)。而在调用过程中无非就是 vector 调用 vector_base 再调用 allocator 再对 _Vector_impl_data 进行操作。还有一个问题在添加元素过程中如果容器满了那么容器的容量是按照怎样的规则递增呢参考了《STL源码刨析》之后得到这样的结论如果超过当前容器容量那么容量会扩增至两倍如果两倍容量仍不够那么就扩张至足够大的容量。在容量的扩张过程中必须经历“重新分配内存元素移动释放原有空间”三个操作这是因为原有的空间之后不一定能够满足需求所以统一进行这三个操作来完成。如何知道是扩增两倍的呢最直观直接的方法就是执行一下这个过程看看例如int main() {    vectorint v;    v.push_back(1);    cout   endl;    // : 1 1    v.push_back(2);    cout   endl;    // : 2 2    v.push_back(3);    cout   endl;    // : 3 4    v.push_back(4);    cout   endl;    // : 4 4    v.push_back(5);    cout   endl;    // : 5 8}这样的容量扩张过程也带来另一个问题当容量为 2 时获取到的 iterator 那么在容量为 8 时还可以用嘛答案是不一定行例如int main() {    vectorint v;    v.push_back(1);    v.push_back(2);    v.push_back(3);    auto iter  v.begin();    cout endl;  // : 1    v.push_back(4);    cout endl;  // : 1    v.push_back(5);    cout endl;  // : 310076128[具体运行结果视内存情况而定]    iter  v.begin();    cout endl;  // : 1}由此可知如果当时的内存环境允许会直接拼到原有容器后面去如果不允许那么就需要把当前容器的内容移动到其他地方去了这时候原来的 iterator 就不能用了。务必小心从这一方面也可以体会到其实 iterator 就是一个类型为传入 vector 中 T 类型的指针。在所有的接口中觉得最有意思的就是 insert 接口了?它的实现过程比较好玩。首先假设调用函数为insert(position, n, x) 而且剩余空间够用那么它需要分成两种情况插入元素个数 n 插入点之后的元素个数 。插入元素个数 n 插入点之后的元素个数 。上面两种情况分别对应下面图中的左右两边内存操作示意图(参考自《STL源码刨析》)在有限的过程和空间里实现最高效的操作不愧是STL???。
http://www.sadfv.cn/news/99136/

相关文章:

  • 商品网站做推广如何做手机app软件
  • 文化传媒网站封面网站源码下载炫酷
  • 山东网站搭建有限公司网站推广公司官网
  • 软件工程考研难度排行番禺区网站优化
  • 丹阳做公司网站注册企业邮箱收费吗
  • 静海的做网站二级域名免费申请
  • 网站建设找哪里中国铁建官网
  • 企业注册资金需要实缴吗seo网站整站优化
  • 非法网站怎么推广杭州规划建设网站
  • wordpress页面跳转成都网站seo服务
  • 邹平网站建设公司网站后台修改内容看不见了
  • 网站建设分金手指排名八wordpress ie6 内核
  • 长尾关键词挖掘爱站工具电子商务的理解
  • 做app网站建设wordpress 调用别名
  • 阳山县网站住房和建设局设计理念
  • 东丽做网站公司门户网站自查报告
  • 免费成品网站模板公司官网网址
  • 网址和网站的区别长沙网站建设zh68
  • 网站建设栏目结构表wordpress 文章php
  • ico 众筹网站开发软件项目实施流程八个阶段
  • 深圳做网站需要多少费用即
  • 现在建网站多少钱重庆网站备案规则
  • 卡盟怎么做网站千页网素材官网入口
  • 做网站在什么地方找我国有哪些企业网站
  • 网站被降权重新做网站视频资源的网站怎么做
  • 互联网客户做网站自己做网站的软件
  • 国外手做网站cute主题 wordpress
  • 大连网站制作美工广东网约车涨价
  • 网站设计主色学校网址价格
  • wap网站建设好不好wordpress添加主题设置功能