• vector


    一、vector的使用

    1.1 vector的定义

    本质讲,vector使用动态分配数组来存储它的元素

    string、vector等都有一个特点,删除数据,一般是不会主动缩容

    构造函数声明
    接口说明
    vector()
    无参构造
    vector(size_type n, const value_type& val = value_type())
    构造并初始化n个val
    vector (const vector& x);
    拷贝构造
    vector (InputIterator fifirst, InputIterator last);
    使用迭代器进行初始化构造
    1. int main()
    2. {
    3. //v1 12345
    4. vector<int> v1;
    5. v1.push_back(1);
    6. v1.push_back(2);
    7. v1.push_back(3);
    8. v1.push_back(4);
    9. v1.push_back(5);
    10. //v2 1.1,2.2,3.3,4.4,5.5
    11. vector<double> v2;
    12. v2.push_back(1.1);
    13. v2.push_back(2.2);
    14. v2.push_back(3.3);
    15. v2.push_back(4.4);
    16. v2.push_back(5.5);
    17. //v3 克里斯蒂亚诺里昂内尔内马尔
    18. vector v3;
    19. v3.push_back("克里斯蒂亚诺");
    20. v3.push_back("里昂内尔");
    21. v3.push_back("内马尔");
    22. //v4构造并初始化10个5
    23. vector<int> v4(10, 5);
    24. //v5 里斯蒂亚诺里昂内尔内马
    25. vector v5(++v3.begin(), --v3.end());
    26. string s = "hello world";
    27. //v6 "hello world"
    28. vector<char> v6(s.begin(), s.end());
    29. return 0;
    30. }

    1.2 vector iterator的使用

    iterator的使用
    接口说明
    begin + end
    获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置的iterator/const_iterator
    rbegin + rend
    获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的
    reverse_iterator
    1. int main()
    2. {
    3. vector<int> v1;
    4. v1.push_back(1);
    5. v1.push_back(2);
    6. v1.push_back(3);
    7. v1.push_back(4);
    8. v1.push_back(5);
    9. //遍历
    10. //1.下标+[]
    11. for (size_t i = 0; i < v1.size(); i++)
    12. {
    13. cout << v1[i] << " ";
    14. }
    15. cout << endl;
    16. //2.迭代器
    17. vector<int> ::iterator it = v1.begin();
    18. while (it != v1.end())
    19. {
    20. cout << *it << " ";
    21. it++;
    22. }
    23. cout << endl;
    24. //3.范围for
    25. for (auto c : v1)
    26. {
    27. cout << c << " ";
    28. }
    29. cout << endl;
    30. return 0;
    31. }

    1.3 vector 迭代器失效问题 

    vector迭代器失效有两种:

    1. 扩容、缩容,导致野指针式失效。
    2. 迭代器指向的意义变了

    vector检查迭代器失效的两种机制:

    1. 系统越界机制检查(不一定能检查到)
    2. 编译实现机制检查(相对靠谱)

    对于insert和erase造成的迭代器失效问题,linux(g++)平台检查很佛系,基本依靠操作系统野指针越界检查机制;windows下VS系列检查更严格,使用一些强制检查机制,意义变了也可能会检查出来

    1.4 vector构建二维动态数组

     

    vector构建动态二维数组时与上图实际是一致的 


    二、vector的模拟实现

    1. namespace Cris
    2. {
    3. template <class T>
    4. class vector
    5. {
    6. public:
    7. typedef T* iterator;
    8. typedef const T* const_iterator;
    9. vector()
    10. :_start(nullptr)
    11. , _finish(nullptr)
    12. , _endofstoage(nullptr)
    13. {}
    14. template <class InputIterator>
    15. vector(InputIterator first, InputIterator last)
    16. : _start(nullptr)
    17. , _finish(nullptr)
    18. , _endofstoage(nullptr)
    19. {
    20. while (first != last)
    21. {
    22. push_back(*first);
    23. ++first;
    24. }
    25. }
    26. vector(size_t n, const T& val = T())
    27. : _start(nullptr)
    28. , _finish(nullptr)
    29. , _endofstoage(nullptr)
    30. {
    31. reserve(n);
    32. for (size_t i = 0; i < n; ++i)
    33. {
    34. push_back(val);
    35. }
    36. }
    37. vector(int n, const T& val = T())
    38. : _start(nullptr)
    39. , _finish(nullptr)
    40. , _endofstoage(nullptr)
    41. {
    42. reserve(n);
    43. for (int i = 0; i < n; ++i)
    44. {
    45. push_back(val);
    46. }
    47. }
    48. void swap(vector& v)
    49. {
    50. std::swap(_start, v._start);
    51. std::swap(_finish, v._finish);
    52. std::swap(_endofstoage, v._endofstoage);
    53. }
    54. vector(const vector& v)
    55. : _start(nullptr)
    56. , _finish(nullptr)
    57. , _endofstoage(nullptr)
    58. {
    59. vector tmp(v.begin(), v.end());
    60. swap(tmp);
    61. }
    62. vector& operator=(vector v)
    63. {
    64. swap(v);
    65. return *this;
    66. }
    67. iterator begin()
    68. {
    69. return _start;
    70. }
    71. iterator end()
    72. {
    73. return _finish;
    74. }
    75. const_iterator begin() const
    76. {
    77. return _start;
    78. }
    79. const_iterator end() const
    80. {
    81. return _finish;
    82. }
    83. size_t size() const
    84. {
    85. return _finish - _start;
    86. }
    87. size_t capacity() const
    88. {
    89. return _endofstoage - _start;
    90. }
    91. void reserve(size_t n)
    92. {
    93. size_t sz = size();
    94. if (n > capacity)
    95. {
    96. T* tmp = new T[n];
    97. if (_start)
    98. {
    99. //扩容使用memcpy拷贝数据是存在浅拷贝问题
    100. //memcpy(tmp, _start, size() * sizeof(T));
    101. //解决方法:
    102. for (size_t i = 0; i < size(); i++)
    103. {
    104. tmp[i] = _start[i];
    105. }
    106. delete[] _start;
    107. }
    108. _start = tmp;
    109. }
    110. _finish = _start + sz;
    111. _endofstoage = _start + n;
    112. }
    113. //T() ---- T的构造函数
    114. //void resize(size_t n,const T& val = T())
    115. void resize(size_t n, T val = T())
    116. {
    117. if (n > capacity())
    118. {
    119. reserve(n);
    120. }
    121. if (n > size())
    122. {
    123. while (_finish < _start + n)
    124. {
    125. *_finish = val;
    126. ++_finish;
    127. }
    128. }
    129. else
    130. {
    131. _finish = _start + n;
    132. }
    133. }
    134. void push_back(const T& x)
    135. {
    136. /*if (_finish == _endofstoage)
    137. {
    138. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
    139. reserve(newCapacity);
    140. }
    141. *_finish = x;
    142. ++_finish;*/
    143. insert(end(), x);
    144. }
    145. void pop_back()
    146. {
    147. if (_finish < _start)
    148. {
    149. --_finish;
    150. }
    151. }
    152. T& operator[](size_t pos)
    153. {
    154. assert(pos < size());
    155. return _start[pos];
    156. }
    157. const T& operator[](size_t pos) const
    158. {
    159. assert(pos < size());
    160. return _start[pos];
    161. }
    162. iterator insert(iterator pos, const T& x)
    163. {
    164. // 检查参数
    165. assert(pos >= _start && pos <= _finish);
    166. // 扩容
    167. // 扩容以后pos就失效了,需要更新一下
    168. if (_finish == _endofstoage)
    169. {
    170. size_t n = pos - _start;
    171. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
    172. reserve(newCapacity);
    173. pos = _start + n;
    174. }
    175. // 挪动数据
    176. iterator end = _finish - 1;
    177. while (end >= pos)
    178. {
    179. *(end + 1) = *end;
    180. --end;
    181. }
    182. *pos = x;
    183. ++_finish;
    184. return pos;
    185. }
    186. iterator erase(iterator pos)
    187. {
    188. assert(pos >= _start && pos < _finish);
    189. iterator it = pos + 1;
    190. while (it != _finish)
    191. {
    192. *(it - 1) = *it;
    193. ++it;
    194. }
    195. --_finish;
    196. return pos;
    197. }
    198. void clear()
    199. {
    200. _finish = _start;
    201. }
    202. private:
    203. iterator _start;
    204. iterator _finish;
    205. iterator _endofstoage;
    206. };
    207. }

     


     

  • 相关阅读:
    CLAHE 算法学习 matlab
    物联网通信技术final fighting
    Unity移动端游戏性能优化简谱之 以引擎模块为划分的CPU耗时调优
    深度学习 神经网络(2)前向传播
    c++中的继承
    java167-生产者消费者问题
    零基础入行软件测试必看,10年测试老鸟的良心建议(共15条)
    【allegro 17.4软件操作保姆级教程七】布线操作基础之二--铜皮操作
    【项目小tips】登录状态存储
    442-C++基础语法(111-120)
  • 原文地址:https://blog.csdn.net/qq_61434514/article/details/125981093