• C++ Vector的模拟实现


    vector的介绍
    1. vector是表示可变大小数组的序列容器。
    2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
    3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
    4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
    5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
    6. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list统一的迭代器和引用更好。

    参考侯捷老师《STL源码刨析》这本书画的:

    Vector的一些接口:

    1. namespace MyVector
    2. {
    3. template<class T>
    4. class vector
    5. {
    6. public:
    7. // Vector的迭代器是一个原生指针
    8. typedef T* iterator;
    9. typedef const T* const_iterator;
    10. iterator begin();
    11. iterator end();
    12. const_iterator cbegin() const;
    13. const_iterator cend() const;
    14. // 初始化
    15. vector();
    16. // 析构
    17. ~vector();
    18. vector(int n, const T& value = T());
    19. vector(size_t n, const T& val = T());
    20. //类模板的成员函数可以是函数模板
    21. template<class InputIterator>
    22. vector(InputIterator first, InputIterator last);
    23. vector(const vector& v);
    24. vector& operator= (vector v);
    25. size_t size() const;
    26. size_t capacity() const;
    27. void reserve(size_t n);
    28. void resize(size_t n, const T& value = T());
    29. T& operator[](size_t pos);
    30. const T& operator[](size_t pos)const;
    31. bool empty();
    32. void push_back(const T& x);
    33. void pop_back();
    34. void swap(vector& v);
    35. iterator insert(iterator pos, const T& x);
    36. iterator erase(iterator pos);
    37. private:
    38. iterator _start = nullptr; // 指向数据块的开始
    39. iterator _finish = nullptr; // 指向有效数据的尾
    40. iterator _endOfStorage = nullptr;// 指向存储容量的尾
    41. };
    42. }

    iterator begin()

    1. iterator begin()
    2. {
    3. return _start;
    4. }

    iterator end()

    1. iterator end()
    2. {
    3. return _finish;
    4. }

    const_iterator cbegin()

    1. const_iterator cbegin()
    2. {
    3. return _start;
    4. }

    const_iterator cend() const

    1. const_iterator cend() const
    2. {
    3. return _finish;
    4. }

    四个比较简单的迭代器

    vector()

    1. vector()
    2. :_start(nullptr)
    3. ,_finish(nullptr)
    4. , _endOfStorage(nullptr)
    5. {}

    ~vector()

    1. ~vector()
    2. {
    3. delete[] _start;
    4. _start = _finish = _endOfStorage;
    5. }

    初始化与析构

    1. //类模板的成员函数可以是函数模板
    2. template<class InputIterator> // InputIterator定义的一个迭代器类型
    3. vector(InputIterator first, InputIterator last)
    4. :_start(nullptr)
    5. , _finish(nullptr)
    6. , _endOfStorage(nullptr)
    7. {
    8. while (first != last)
    9. {
    10. push_back(*first);
    11. ++first;
    12. }
    13. }

    vector& operator= (vector v)

    1. vector& operator= (vector v)
    2. {
    3. swap(v);
    4. return *this;
    5. }

            // v1 = v3

    size_t size() const

    1. size_t size() const
    2. {
    3. return _finish - _start;
    4. }

            // 有效数据的尾减去数据块的开始就是元素个数

    size_t capacity() const

    1. size_t capacity() const
    2. {
    3. return _endOfStorage - _start;
    4. }

            // 开辟空间的容量

    void reserve(size_t n)

    1. void reserve(size_t n)
    2. {
    3. if (n > capacity())
    4. {
    5. T* tmp = new T[n];
    6. size_t old_size = size();
    7. for (size_t i = 0; i < old_size; i++)
    8. {
    9. tmp[i] = _start[i]; // 深拷贝
    10. }
    11. delete[] _start;
    12. _start = tmp; // 老的_start已经失效,更新一下
    13. _finish = tmp + old_size;
    14. _endOfStorage = tmp + n;
    15. }
    16. }

    void resize(size_t n, const T& value = T())

    1. void resize(size_t n, const T& value = T())
    2. {
    3. if (n > size()) // 超过就扩容
    4. {
    5. reserve(n);
    6. while (_finish < _start + n)
    7. {
    8. *_finish = value;
    9. ++_finish;
    10. }
    11. }
    12. else
    13. {
    14. _finish = _start + n;
    15. }
    16. }

    vector(const vector& v)

    1. vector(const vector& v)
    2. {
    3. reserve(v.capacity());
    4. for (auto& e : v)
    5. {
    6. push_back(e);
    7. }
    8. }

            // v2(v1) 用已经存在的 v1 去初始化 v2

    T& operator[](size_t pos)

    const T& operator[](size_t pos)const

    1. T& operator[](size_t pos)
    2. {
    3. assert(pos < size()); // 保证下标为有效数据
    4. return _start[pos];
    5. }
    6. const T& operator[](size_t pos)const
    7. {
    8. assert(pos < size());
    9. return _start[pos];
    10. }

    iterator insert(iterator pos, const T& x)

    1. iterator insert(iterator pos, const T& x)
    2. {
    3. assert(pos >= _start);
    4. assert(pos <= _finish);
    5. if (_finish == _endOfStorage)
    6. {
    7. size_t len = pos - _start;
    8. reserve(capacity() == 0 ? 4 : 2 * capacity());
    9. //如果扩容了要更新pos
    10. pos = _start + len;
    11. }
    12. iterator it = _finish - 1;
    13. while (it >= pos)
    14. {
    15. *(it + 1) = *it;
    16. --it;
    17. }
    18. *pos = x;
    19. ++_finish;
    20. }

    iterator erase(iterator pos)

    1. iterator erase(iterator pos)
    2. {
    3. assert(pos >= _start);
    4. assert(pos <= _finish);
    5. iterator it = pos + 1;
    6. while (it < _finish)
    7. {
    8. *(it - 1) = *it;
    9. --it;
    10. }
    11. --_finish;
    12. return pos;
    13. }

    vector(int n, const T& value = T())

    1. vector(int n, const T& value = T())
    2. {
    3. reserve(n);
    4. for (size_t i = 0; i < n; i++)
    5. {
    6. push_back(value);
    7. }
    8. }

    vector(size_t n, const T& val = T())

    1. vector(size_t n, const T& val = T())
    2. {
    3. reserve(n);
    4. for (size_t i = 0; i < n; i++)
    5. {
    6. push_back(val);
    7. }
    8. }

    bool empty()

    1. bool empty()
    2. {
    3. return _start == _finish;
    4. }

    void push_back(const T& x)

    1. void push_back(const T& x)
    2. {
    3. insert(end(), x);
    4. }

    void pop_back()

    1. void pop_back()
    2. {
    3. erase(end() - 1);
    4. }

    void swap(vector& v)

    1. void swap(vector& v)
    2. {
    3. std::swap(_start, v._start);
    4. std::swap(_finish, v._finish);
    5. std::swap(_endOfStorage, v._endOfStorage);
    6. }

    完整代码:

    1. #pragma once
    2. #include
    3. namespace bit
    4. {
    5. template<class T>
    6. class vector
    7. {
    8. public:
    9. // Vector的迭代器是一个原生指针
    10. typedef T* iterator;
    11. typedef const T* const_iterator;
    12. iterator begin()
    13. {
    14. return _start;
    15. }
    16. iterator end()
    17. {
    18. return _finish;
    19. }
    20. const_iterator cbegin()
    21. {
    22. return _start;
    23. }
    24. const_iterator cend() const
    25. {
    26. return _finish;
    27. }
    28. // construct and destroy
    29. vector()
    30. :_start(nullptr)
    31. ,_finish(nullptr)
    32. , _endOfStorage(nullptr)
    33. {}
    34. vector(int n, const T& value = T())
    35. {
    36. reserve(n);
    37. for (size_t i = 0; i < n; i++)
    38. {
    39. push_back(value);
    40. }
    41. }
    42. vector(size_t n, const T& val = T())
    43. {
    44. reserve(n);
    45. for (size_t i = 0; i < n; i++)
    46. {
    47. push_back(val);
    48. }
    49. }
    50. //类模板的成员函数可以是函数模板
    51. template<class InputIterator>
    52. vector(InputIterator first, InputIterator last)
    53. :_start(nullptr)
    54. , _finish(nullptr)
    55. , _endOfStorage(nullptr)
    56. {
    57. while (first != last)
    58. {
    59. push_back(*first);
    60. ++first;
    61. }
    62. }
    63. vector(const vector& v)
    64. {
    65. reserve(v.capacity());
    66. for (auto& e : v)
    67. {
    68. push_back(e);
    69. }
    70. }
    71. vector& operator= (vector v)
    72. {
    73. swap(v);
    74. return *this;
    75. }
    76. ~vector()
    77. {
    78. delete[] _start;
    79. _start = _finish = _endOfStorage;
    80. }
    81. size_t size() const
    82. {
    83. return _finish - _start;
    84. }
    85. size_t capacity() const
    86. {
    87. return _endOfStorage - _start;
    88. }
    89. void reserve(size_t n)
    90. {
    91. if (n > capacity())
    92. {
    93. T* tmp = new T[n];
    94. size_t old_size = size();
    95. for (size_t i = 0; i < old_size; i++)
    96. {
    97. tmp[i] = _start[i];
    98. }
    99. delete[] _start;
    100. _start = tmp;
    101. _finish = tmp + old_size;
    102. _endOfStorage = tmp + n;
    103. }
    104. }
    105. void resize(size_t n, const T& value = T())
    106. {
    107. if (n > size())
    108. {
    109. reserve(n);
    110. while (_finish < _start + n)
    111. {
    112. *_finish = value;
    113. ++_finish;
    114. }
    115. }
    116. else
    117. {
    118. _finish = _start + n;
    119. }
    120. }
    121. T& operator[](size_t pos)
    122. {
    123. assert(pos < size());
    124. return _start[pos];
    125. }
    126. const T& operator[](size_t pos)const
    127. {
    128. assert(pos < size());
    129. return _start[pos];
    130. }
    131. bool empty()
    132. {
    133. return _start == _finish;
    134. }
    135. void push_back(const T& x)
    136. {
    137. insert(end(), x);
    138. }
    139. void pop_back()
    140. {
    141. erase(end() - 1);
    142. }
    143. void swap(vector& v)
    144. {
    145. std::swap(_start, v._start);
    146. std::swap(_finish, v._finish);
    147. std::swap(_endOfStorage, v._endOfStorage);
    148. }
    149. iterator insert(iterator pos, const T& x)
    150. {
    151. assert(pos >= _start);
    152. assert(pos <= _finish);
    153. if (_finish == _endOfStorage)
    154. {
    155. size_t len = pos - _start;
    156. reserve(capacity() == 0 ? 4 : 2 * capacity());
    157. //如果扩容了要更新pos
    158. pos = _start + len;
    159. }
    160. iterator it = _finish - 1;
    161. while (it >= pos)
    162. {
    163. *(it + 1) = *it;
    164. --it;
    165. }
    166. *pos = x;
    167. ++_finish;
    168. }
    169. iterator erase(iterator pos)
    170. {
    171. assert(pos >= _start);
    172. assert(pos <= _finish);
    173. iterator it = pos + 1;
    174. while (it < _finish)
    175. {
    176. *(it - 1) = *it;
    177. --it;
    178. }
    179. --_finish;
    180. return pos;
    181. }
    182. private:
    183. iterator _start = nullptr; // 指向数据块的开始
    184. iterator _finish = nullptr; // 指向有效数据的尾
    185. iterator _endOfStorage = nullptr;// 指向存储容量的尾
    186. };
    187. }

    测试代码:

    1. #include
    2. #include
    3. #include
    4. #include "Vector.h"
    5. using namespace std;
    6. int main()
    7. {
    8. vector<int> v;
    9. v.push_back(1);
    10. v.push_back(2);
    11. v.push_back(3);
    12. v.push_back(4);
    13. v.push_back(5);
    14. cout << v.size() << endl;
    15. cout << v.capacity() << endl;
    16. for (size_t i = 0; i < v.size(); i++)
    17. {
    18. cout << v[i] << " ";
    19. }
    20. cout << endl;
    21. for (auto e : v)
    22. {
    23. cout << e << " ";
    24. }
    25. cout << endl;
    26. v.reserve(30);
    27. cout << v.capacity() << endl;
    28. vector<int>::iterator it = v.begin();
    29. while (it != v.end())
    30. {
    31. cout << *it << " ";
    32. ++it;
    33. }
    34. cout << endl;
    35. vector<int> v1(v);
    36. v1.push_back(100);
    37. v1.push_back(200);
    38. v1.pop_back();
    39. for (auto e : v1)
    40. {
    41. cout << e << " ";
    42. }
    43. }

  • 相关阅读:
    中兴通讯5G为何要开拓第二曲线业务?一切都是为了得到更好的发展!
    中科创达怎么样-是外包公司吗-智能网联汽车和智能物联网推动业务快速增长
    LeetCode_单调栈_中等_456.132 模式
    含冰蓄冷空调的冷热电联供型微网多时间尺度优化调度
    11月19日绿健简报,星期六,农历十月廿六
    阅读JavaScript文档-一些常用方法
    Leetcode 104. 二叉树的最大深度
    48页智慧城市规划蓝图 解决方案
    安全算法 - 国密算法
    解释一下前端框架中的虚拟DOM(virtual DOM)和实际DOM(real DOM)之间的关系。
  • 原文地址:https://blog.csdn.net/qq_73874574/article/details/139888695