zoukankan      html  css  js  c++  java
  • vector的实现细节

    1、vector类的主要数据成员

    vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。

    vector类中主要有三根指针start, finish和end_of_storage

     1 template <typename T>
     2 class vector
     3 {
     4 public:
     5     typedef T value_type;
     6     typedef value_type* iterator;
     7     ...  
     8 protected:
     9     iterator start;
    10     iterator finish;
    11     iterator end_of_storage;
    12     ...
    13 };

    其中start是指向当前使用空间的起始位置

          finish是指向当前使用空间末尾元素的下一个位置

          end_of_storage是指向当前分配的可使用空间的最后一个位置的下一个位置

    2、vector的迭代器

    vector维护的是一个连续空间,所以不论其元素的类型是什么,普通指针都可以作为vector的迭代器,可以满足vector迭代器所需要的所有操作行为,vector支持随机存取,而普通指针正有着这样的能力,所以vector的迭代器是一个Random Access Iterator

    3、vector如何实现动态数组

    当vector的预留空间无法满足时,vector就会扩张空间,将重新分配两倍的当前空间大小,将现有空间的所有对象移动到新的空间里,在释放掉原空间,如下图

    下面是vector的成员函数push_back的实现

     1 void push_back(const T& x) {
     2     //拥有预留空间    
     3     if (finish != end_of_storage) {
     4         std::allocator<T>().construct(finish, x);
     5         ++finish;
     6     } 
     7     //没有预留空间
     8     else
     9         inset_axu(end(), x);
    10 }

    可以看出动态分配空间技巧的实现落在了insert_axu()身上

     1 template<typename T>
     2 void Vector<T>::insert_axu(Vector::iterator position, const T &x) {
     3     //Vector拥有备用空间
     4     if (finish != end_of_storage) {                                                      
     5         std::allocator<T>().construct(finish, *(finish-1));
     6         ++finish;
     7         T x_copy = x;
     8         std::copy_backward(position, finish-2, finish-1);
     9         *position = x_copy;
    10 
    11     }
    12     //Vector没有备用空间
    13     else {                                                                               
    14         const size_type old_size = size();
    15         //当原来空间大小不为零时分配原来空间大小二倍的空间
    16         const size_type len = old_size == 0 ? 1 : 2 * old_size;                          
    17         iterator new_start = std::allocator<T>().allocate(len);
    18         iterator new_finish = new_start;
    19         try {
    20             //将原vector插入位置之前的内容拷贝到新vector
    21             new_finish = std::uninitialized_copy(start, position, new_start);
    22             //在新配置空间的finish位置设定要插入的对象
    23             std::allocator<T>().construct(new_finish, x);
    24             //更新新finish指向的位置
    25             ++new_finish;
    26             //将原vector插入位置之后的内容拷贝到新vector
    27             new_finish = std::uninitialized_copy(position, finish, new_finish);          
    28         }
    29         //若分配新空间时出现异常,则析构并释放新空间
    30         catch(...) {                                                                     
    31             auto iter = new_start;
    32             for (; iter != new_finish; ++iter)
    33                 std::allocator<T>().destroy(iter);
    34             std::allocator<T>().deallocate(new_start, len);
    35             throw;
    36         }
    37         //析构并释放原vector
    38         auto iter = begin();                                                             
    39         for (; iter != end(); ++iter)
    40             std::allocator<T>().destroy(iter);
    41         deallocate();
    42         //调整迭代器
    43         start = new_start;                                                               
    44         finish = new_finish;
    45         end_of_storage = new_finish + len;
    46 
    47     }
    48 }

    具体实现详见 https://github.com/anoov/myTinySTL/tree/master/myTinySTL

  • 相关阅读:
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    自考感悟,话谈备忘录模式
    [每日一题] OCP1z0-047 :2013-07-26 alter table set unused之后各种情况处理
    Java实现 蓝桥杯 算法提高 p1001
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 因式分解
    Java实现 蓝桥杯 算法提高 因式分解
  • 原文地址:https://www.cnblogs.com/swenwen/p/12526804.html
Copyright © 2011-2022 走看看