STL源码剖析精简版之 vector

   研究侯捷的<<STL源码剖析>>有点难度(当然如果您是高手的话会很简单),从Meyer Scott 200多页的<<Effective STL>>找出要使用的方法的注意事项也不大简单,即使找到也会因不知道内部实现而不理解也很常见,以下提供 Vector 简略的实现原理及使用某些方法时注意事项。

Vector

(sgi-stl-2.91.57)

(i). Vector 的内存分布示意图.(size = finish - satrt, capacity = end_of_storage - start).

       图片

 (ii). vector处于如下状态时,再插入一个元素则会引起内存重新分配及元素移动.如图(ii) – 1, (ii) – 2 为在位置pos前插入一元素val后的状态。内存扩大三部曲:(1). 寻找更大的内存空间(2);(2). 把原有元素从旧内存移动到新内存; (3). 释放旧内存空间。只要涉及到内存重新分配先前的iterator都失效,涉及到元素移动则看情况.

图片
 

Vector 的构造函数:

vector();

vector( size_type num, const T &val );

vector( const vector &from );

vector( InputIterator start, InputIterator end );

 

Vector重载的比较运算符:

v1 == v2; v1 != v2; v1 <= v2; v1 >= v2; v1 < v2; v1 > v2 ; v[]

 

1.     void swap( vector &from );

    复杂度: O(1)

  功能:交换两个 vector

  实现细节: 交换start, finish, end_of_storage. 使用全局函数 swap(T&, T&)

 

2.     int size();

复杂度: O(1)

功能:返回 vector 的元素的个数

实现细节: return finish – start

 

3.     void resize(size_type new_size, cosnt T& value);

resize(size_type new_size);

复杂度:O(|new_size – size()|)

功能:扩大或者缩小vector size (size为元素个数,非capacity)

实现细节:

(1). new_size < size, 调用 erase(begin() + new_size, end()); 删除多余元素.

(2). new_size > size, 调用 insert(end(), new_size-size(), T(value));或者 insert(end(), new_size-size(), T());

    注意: (1)涉及元素删除,所以旧的vector[begin() + new_size, end()) 之间的

    iterator 失效. (2). 涉及元素的插入,有可能引起内存重新分配和元素移动,所

  以 iterator 很有可能失效.

4.     void reserve(size_type n);

  复杂度: n > size() , O(n - size);

   功能: 如果 n > size() 则预留 n 个空间(capacitysize),否则什么都不做.

  现细节:申请新的空间并移动元素,析构旧空间里的元素并释放旧的内存

  空间,重新设置satart, finish, end_of_storage

  注意: 调用reserve(size_type n) 后如果有内存分配和元素移动,所以之前的

    iterator 全部失效.

                      

5.     reverse_iterator rbegin();reverse_iterator rend()
   功能:返回 vector 末尾的逆 iterator; 返回 vector 开始的逆 iterator. 因为 reverse_iterator 重载了 ++(相当于正常的 --), -- (相当于正常的 ++)等运算符所以可以像正常 iterator 一样使用. reserve_iterator  “*” 源码如下:

reference operator*() const

{

              _Iterator __tmp = current;

              return *--__tmp;

    }

 

6.     void push_back(const T& value);

复杂度:finish != end_of_storage O(1), 否则为 O(size());

功能: vector 的末尾添加 value

实现细节:

(1). If(finish != end_of_storage)   // 没有达到尾端

      直接添加元素

(2). // 已经达到了尾端. 重新分配内存移动元素.

注意: 由于(2) 存在重新分配内存和移动元素,所以使用push_back()时先前的 iterator 有可能失效.

 

7.     void pop_back();
复杂度: O(1)
功能: 删除 vector 尾端的元素, capacity 没有改变。
实现细节: 直接删除即可.
注意: 由于删除时没有检查 vector 是否为空,所以检查是否为空由用户手动检查。

 

8.     size_type max_size();
功能: 返回0xFFFFFFFF最大能存贮多少个T
实现细节: 
size_type max_size() const { return size_type(-1) / sizeof(T); }

9.     iterator insert(iterator position, const T& x);

复杂度: O(size())

功能: position 前插入元素 x, 并返回指向 x iterator.

position前插入x而不是在后插入x原因在于如果position == end() 则在position后插入则会出现一个漏洞.

实现细节:

(1). Vector 还有剩余空间 && position == end(), 则直接插入.

(2). 如果还有剩余空间则把 [position, end()) 往后移动一个位置再插入 x.

(3). 如果没有剩余空间则重新分配2倍于旧的 vector 的容量,移动元素旧的[start, position), 添加 x, 移动[postion, end()).

注意: (2)涉及[position, end())元素的移动,所以[postion, end())区间的 iterator 失效. (3)涉及内存重新分配元素移动,所以所有的iterator失效。

 

另外两个版本的 insert. 功能及实现都类似,在此不做说明。

void insert( iterator loc, size_type num, const TYPE &val );
void insert( iterator loc, input_iterator start, input_iterator end );

9. reference front();

  功能: 返回 vector 的第一个元素.

 

10. iterator erase( iterator position );

复杂度: O(size())

    功能: 删除 position 并返回下一个元素的 iterator

    实现细节:

    如果 position != end() 则把[position + 1, end()) 往前移动一个单位,-- finish,

   析构最后一个元素(destroy(finish)).

  注意: 在删除元素 position 后,先前在[position, end())区间的 iterator 都失效.

   如果要删除所有与某一元素相等的元素可使用.erase-remove.如下:

   v.erase(remove(v.begin(), v.end(), val), end()).(remove(…)为全局函数,它不删除

 元素,只是把元素向前移动把符合条件的元素给覆盖掉而已) 或者使用for()

  如下:

      For (iterator iter = v.begin(); iter != v.end(); )

     {

          If (*iter == val)

        {

             // 释放资源.

             Iter = v.erase(iter);

        }

        Else  ++ iter;

    }

  另一个版本的 erase,功能和实现细节类似,在此不再陈述..

    iterator erase(iterator first, iterator last);

 

   11. iterator begin(); iterator end(); bool empty(); void clear();

   size_type capacity(); reference back(); 等函数就如它们的名字所描述那样.

 

参考书目:

1. <<STL 源码剖析>>             侯捷

2. <<C++标准程序库>>          侯捷/孟岩 译

3. <<Effective STL>>               Meyer Scott

 

                                                                                                  陈学全

                                                                                                  2009-09-12

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值