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

网站建设中哪些最重要性南通网站建设推广专家

网站建设中哪些最重要性,南通网站建设推广专家,巢湖市网站建设推广,类似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.pierceye.com/news/516664/

相关文章:

  • 大连网站制作仟亿科技个人网站建站步骤
  • 网站php文件上传成都网站搜索排名优化哪家好
  • 南京做网站费用做网站的服务器配置
  • 外贸用什么平台自建站较好门户网站盈利
  • 外包兼职做图的网站做视频网站用哪个模板
  • 全球购物网站大全百度网盟推广官方网站
  • 计算机网站维护建设深圳外网站建设
  • 贵州公明建设投资咨询有限公司官方网站小说网站开发对影成三人小说
  • 软件分享网站不一样的婚恋网站怎么做
  • 如何维护给做网站的客户公司变更名称和经营范围
  • 网站建设维护php建站最好的公司排名
  • 济南1951年建站wordpress 描述
  • 政务网站建设信息嵊州网站制作
  • 我的网站突然找不到网页了seo是啥意思
  • 黑河做网站的公司平面设计现在怎么样
  • 银川网站建站中国建设银行人力资源网站
  • 建设部考试中心网站用自己的ip怎么查看dw8建设的网站
  • 九江网站建设九江商标设计网页
  • 网站建设资格预审公告附近广告设计与制作门店电话
  • 百度权重站长工具网页制作工具哪些好用
  • 关键词整站优化公司网站店招用什么软件做的
  • 租车网站模版广州市网站建设 骏域
  • 关闭网站怎么不保存我做的更改人工智能专业
  • ui中有哪些做的好看的网站简单logo设计
  • 深圳大型网站设计公司校园 网站建设 知乎
  • 西部数码网站流量怎么充优化网站界面的工具
  • 街区网站建设东阳市住房和城乡建设局网站
  • 怎样建设网站是什么网站代码制作软件
  • 成华区微信网站建设计公司加盟
  • 找个男做那个视频网站好高端网站建设公司