vector的实现细节

Posted swenwen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

 

以上是关于vector的实现细节的主要内容,如果未能解决你的问题,请参考以下文章

[C++]Deque with iterator实现细节

c++ stl里的向量vector非常好用,那么它是怎么实现的呢

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段

STL之vector

单个活动:带有 AppBarLayout 的片段

java知识28 Java封装多测师