STL vector实现

STL vector实现

分类: C++   3279人阅读   评论(0)   收藏   举报
vector iterator reference insert distance class

假定你现在已经能熟练使用vector,如果你很好奇vector背后是怎么实现的,那么本文或许对你能有所帮助。

  vector代表了c++的动态数组,大小是动态可增长的。你不必考虑自己手动分配或释放内存,也不必担心内存泄漏,vector帮你做了这一切。vector的使用很简单,但是要做到有效率,没那么容易,了解他背后的实现原理能帮助达到这一目的。

  言归正传。本文基于SGI STL的一个vector的实现,向大家讲述vector的实现思想和技术,如有不妥的地方,还请大家给出批评建议。(建议大家在阅读本文之前,先能温习一下vector的相关内容和用法)。

  让我们先看看类的声明和数据成员:

#include <alloc.h>  //内存分配器头文件,非标准

#include <iterator.h> //迭代器头文件,非标准

template <class T > //模板类声明,提供泛型功能。
class vector {
  typedef alloc Alloc;  //内存分配器typedef
public:
    typedef T value_type;  //值类型 T
    typedef value_type* pointer; // 指针类型 T*
    typedef value_type* iterator; //迭代器,这里的迭代器不需要封装,只是一个原生指针的typedef
    typedef const value_type* const_iterator; // 只读迭代器
    typedef value_type& reference;  //引用 T&
    typedef const value_type& const_reference;  //只读引用
    typedef size_t size_type;  //长度类型 size_t,一般是unsigned int;
    typedef ptrdiff_t difference_type; // 指针间隔,用来表示两个指针间的距离
    typedef reverse_iterator<const_iterator, value_type, const_reference, 
                             difference_type>  const_reverse_iterator; //反向迭代器,定义在<iterator.h>
    typedef reverse_iterator<iterator, value_type, reference, difference_type>
        reverse_iterator; //只读反向迭代器
protected:

   //数据成员

    typedef simple_alloc<value_type, Alloc> data_allocator; //分配器的typedef
    iterator start; //vector的第一个元素的迭代器,用来表示vector,永远为vector.begin();
    iterator finish;  //vector的末尾,指向vector的最后一个元素的下一个位置。永远为vector.end();
    iterator end_of_storage; //vector所拥有的内存的末尾。如果等于vector.end(),表示vector已满

}

  从以上我们可以看到,vector用allocator来进行内存管理,用三个迭代器来引用这段内存。vector的iterator 其实就是T*的别名。我们知道在一个连续的内存里(数组),指针是可以做算术运算的,也支持[]操作,所以vector的iterator也支持算术运 算,++,--,+=, -=,[],vector的迭代器就是通常的随机访问迭代器了。

  另外,我想说的是,STL有许多流行的版本,每一个版本实现都不是相同的,但是原理区别不大。vector的底层实现一般是连续的内存(数组)。 deque的实现是连续的内存块,list的是双链表,set和map是红黑树。stack和queue都是这些容器的适配器(用这些容器来实现)。知道 这些是很有必要的。

  下一篇文章里,将会讨论到vector的常用接口的实现。

上一篇我们讨论了vector的声明,接下来您将看到的是vector的接口和实现。

  class vector {

   public:

   ...

    iterator begin() { return start; } //返回vetor的首
    const_iterator begin() const { return start; } //只读访问
    iterator end() { return finish; } //返回vector的末尾
    const_iterator end() const { return finish; } //只读访问
    reverse_iterator rbegin() { return reverse_iterator(end()); } //反向迭代器
    const_reverse_iterator rbegin() const { 
        return const_reverse_iterator(end()); 
    } //只读访问
    reverse_iterator rend() { return reverse_iterator(begin()); } //反向迭代器
    const_reverse_iterator rend() const { 
        return const_reverse_iterator(begin()); 
    }
    size_type size() const { return size_type(end() - begin()); } //size,vector的长度
    size_type max_size() const { return size_type(-1); }  //vector支持的最大长度,4294967295
    size_type capacity() const { return size_type(end_of_storage - begin()); } //vector的当前   容量.表示当前的vector有多大的容量。
    bool empty() const { return begin() == end(); } //判断vetor是否为空,实现保证这个函数永远是常量时间复杂度。判断vector为空间已用empty,不要用size()==0,因为 size()有可能是线性时间复杂度。
    reference operator[](size_type n) { return *(begin() + n); } //  []操作符
    const_reference operator[](size_type n) const { return *(begin() + n); } //只读

   vector() : start(0), finish(0), end_of_storage(0) {} //默认构造函数

   vector(size_type n, const T& value) {  //初始化长度为n,每个值均为value的vetor
    start = data_allocator::allocate(n); //vector的内存分配委托给allocator来实现
    iterator first = start;

    while(n--)

    {

         *first++ = value;

    }
    finish = start + n;
    end_of_storage = finish;
    }


    vector(size_type n) { //初始化长度为n,每个值均为默认值的vector
    start = data_allocator::allocate(n);
    while(n--)

    {

         *first++ = T();

    }   

    finish = start + n;
    end_of_storage = finish;
    }


    vector(const vector<T /*, Alloc*/>& x) {  //拷贝构造函数
    start = data_allocator::allocate(x.end() - x.begin());

    finish = start;

    for(iterator i = x.begin(); i != x.end(); ++i )

    {

        *finish++ = *i;

    }
    end_of_storage = finish;
    }

    
    vector(const_iterator first, const_iterator last) { //迭代器构造函数
    size_type n = 0;
    distance(first, last, n); //判断first到last的距离
    start = data_allocator::allocate(n);
    finish = start;

    for(iterator i = x.begin(); i != x.end(); ++i )

    {

        *finish++ = *i;

    }
    end_of_storage = finish;
    }


    ~vector() {   //vector的析构函数
    destroy(start, finish);  //调用每个元素的析构函数
    deallocate(); //释放vector的内存
    }
    vector<T /*, Alloc*/>& operator=(const vector<T /*, Alloc*/>& x);
    void reserve(size_type n) {  //vector的reverse函数,主要是用作vector的扩容,增加vector的容量到 n所制定的大小。为了防止vector发生过多的插入拷贝,建议用此函数为vector申请足够大的容量
    if (capacity() < n) {
            const size_type old_size = size();
        const iterator tmp = data_allocator::allocate(n);
        uninitialized_copy(begin(), end(), tmp);
        destroy(start, finish);
        deallocate();
        start = tmp;
        finish = tmp + old_size;
        end_of_storage = start + n;
    }
    }
    reference front() { return *begin(); } //返回vector的第一个元素
    const_reference front() const { return *begin(); } //
    reference back() { return *(end() - 1); } //返回vector的最后一个元素
    const_reference back() const { return *(end() - 1); } 
    void push_back(const T& x) {   //vector的push_back,最常用的函数,想vector的末尾增加值
    if (finish != end_of_storage) {
        *finish = x;
        ++finish;
    } else
        insert_aux(end(), x); //如果vector容量已满,进行插入。
    }
    void swap(vector<T /*, Alloc*/>& x) { //交换两个vector的值.这个是很有效率的。常量时间交换。
    ::swap(start, x.start);
    ::swap(finish, x.finish);
    ::swap(end_of_storage, x.end_of_storage);
    }

    
    iterator insert(iterator position, const T& x) { //vector的插入函数
    size_type n = position - begin();
    if (finish != end_of_storage && position == end()) {
        *finish = *position;
        ++finish;
    } else
        insert_aux(position, x); //vector的插入需要拷贝调整元素的位置,因而需要拷贝,效率低
    return begin() + n;
    }
    iterator insert(iterator position) { return insert(position, T()); }
    void insert (iterator position, const_iterator first, 
         const_iterator last);
    void insert (iterator position, size_type n, const T& x);
    void pop_back() {  弹出最后一个元素
        --finish;            
        destroy(finish);
    }
    void erase(iterator position) { //删除vector的元素,删除最后一个值是常量时间,否则需要调整元素,重新拷贝,效率很低
    if (position + 1 != end())
        copy(position + 1, end(), position);
    --finish;
    destroy(finish);
    }
    void erase(iterator first, iterator last) {
    vector<T /*, Alloc*/>::iterator i = copy(last, end(), first); //需要重新拷贝
    destroy(i, finish); //删除需要删除的位置
    finish = finish - (last - first); 
    }
    void resize(size_type new_size, const T& x) { //调整vector的长度
      if (new_size < size()) 
        erase(begin() + new_size, end());
      else
        insert(end(), new_size - size(), x);
    }
    void resize(size_type new_size) { resize(new_size, T()); }
    void clear() { erase(begin(), end()); } //清除vector的所有元素,实现保证这个是线性时间的,O(n).

 }

vector的常用接口就说到这里了,大家可以仔细体会。

你可能感兴趣的:(C++)