当前位置:   article > 正文

【c++vector】vector的实现和深层次的深浅拷贝_c++ vector 深拷贝

c++ vector 深拷贝

目录

 

1.深层次的深浅拷贝

2.vector的实现

                2.迭代器和打印函数

                3.reserve和resize

                4.拷贝构造函数和赋值运算符重载

                5.插入和删除 

                全部代码


1.深层次的深浅拷贝

步骤:

  1. 自己的实现容量初始为4个,增容2倍,当尾插的4个数,再插入第5个数时会发生增容;
  2. 使用memcpy增容或者拷贝构造,都会是深层次的浅拷贝

总结:

  1. T是内置类型(int)或者是浅拷贝自定义类型(date),他们增容和拷贝构造中,使用memcpy是没有问题的;
  2. 但是T是深拷贝自定义类型(string),他们增容和拷贝构造中,使用memcpy浅拷贝,指向1块相同的空间,是有问题的;
  3. STL库里面是类型萃取区分类型(了解):memcpy效率更高(内置类型,浅拷贝自定义类型),遍历+深拷贝自定义类型(string)的赋值运算符重载会,开空间+拷贝构造效率更低(深拷贝自定义类型)

解决:把memcpy替换为遍历+深拷贝自定义类型(string)的赋值运算符重载;

  1. for (size_t i = 0; i < v.size(); i++)//解决深层次的深浅拷贝
  2. {
  3. _start[i] = v._start[i];
  4. }

逻辑如图:

代码: 

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<assert.h>
  4. #include<string>
  5. using namespace std;
  6. namespace lj
  7. {
  8. template<class T>
  9. class vector
  10. {
  11. public:
  12. typedef T* iterator;
  13. typedef const T* const_iterator;
  14. vector(const vector<T>& v)//拷贝构造
  15. :_start(nullptr)
  16. ,_finish(nullptr)
  17. ,_endofstorage(nullptr)
  18. {
  19. _start = new T[v.capacity()];
  20. memcpy(_start, v._start, sizeof(T) * v.capacity());
  21. //for (size_t i = 0; i < v.size(); i++)//解决深层次的深浅拷贝
  22. //{
  23. // _start[i] = v._start[i];
  24. //}
  25. _endofstorage = _start + v.capacity();
  26. _finish = _start + v.size();
  27. }
  28. void reserve(size_t n)
  29. {
  30. if (n > capacity())
  31. {
  32. size_t sz = size();
  33. iterator tmp = new T[n];
  34. if (_start)//start不为为空
  35. {
  36. memcpy(tmp, _start, sz*sizeof(T));
  37. //for (size_t i = 0; i << sz; i++)
  38. //{
  39. //tmp[i] = _start[i];
  40. //}
  41. delete[] _start;
  42. }
  43. _start = tmp;
  44. _finish = _start+sz;
  45. _endofstorage=_start+n;
  46. }
  47. }
  48. void push_back(const T& x)
  49. {
  50. if (_finish == _endofstorage)
  51. {
  52. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
  53. reserve(newCapacity);
  54. }
  55. *_finish = x;
  56. _finish++;
  57. }
  58. private:
  59. iterator _start;
  60. iterator _finish;
  61. iterator _endofstorage;
  62. };
  63. void test_vector6()
  64. {
  65. vector<string> v;
  66. v.push_back("1111");
  67. v.push_back("2222");
  68. v.push_back("3333");
  69. v.push_back("4444");
  70. v.push_back("5555");
  71. vector<string> v1(v);
  72. v.PrintVector();
  73. v1.PrintVector();
  74. }
  75. }
  76. int main()
  77. {
  78. lj::test_vector6();
  79. return 0;
  80. }

2.vector的实现

                1.构造函数和析构函数

  • 使用迭代器构造函数时,可以是任意类型(int,sting,double)所以把迭代器构造函数写成一个模板函数;类模板的成员函数,还可以再是函数模板
  1. vector()
  2. :_start(nullptr)
  3. ,_finish(nullptr)
  4. ,_endofstorage(nullptr)
  5. {}
  6. // 类模板的成员函数,还可以再是函数模板
  7. template<class InputIterator>
  8. vector(InputIterator first, InputIterator last)
  9. : _start(nullptr)
  10. , _finish(nullptr)
  11. , _endofstorage(nullptr)
  12. {
  13. while (first != last)
  14. {
  15. push_back(*first);
  16. ++first;
  17. }
  18. }
  19. ~vector()
  20. {
  21. if (_start)
  22. {
  23. delete[] _start;
  24. _start = _finish = _endofstorage = nullptr;
  25. }
  26. }

                2.迭代器和打印函数

  • 一个接口需要可读和可读可写的时候,那么写成两份
  1. const_iterator begin()const
  2. {
  3. return _start;
  4. }
  5. const_iterator end()const
  6. {
  7. return _finish;
  8. }
  9. iterator begin()
  10. {
  11. return _start;
  12. }
  13. iterator end()
  14. {
  15. return _finish;
  16. }
  17. void PrintVector()const
  18. {
  19. vector<T>::const_iterator it = this->begin();
  20. while (it != this->end())
  21. {
  22. //*it += 1;//只能读,不能写
  23. cout << *it << " ";
  24. ++it;
  25. }
  26. cout << endl;
  27. }

                3.reserve和resize

  • reserve最后_finish = _start+sz;和_endofstorage=_start+n;不能写成_start+size()和_start+capacity(),因为计算是_finish和_endofstorage还是nullptr,求size()和capacity()会是一个很大的负值
  • resize3中情况:减少size;增加size,但是不用增容;增加size也需要增容
  1. void reserve(size_t n)
  2. {
  3. if (n > capacity())
  4. {
  5. size_t sz = size();
  6. iterator tmp = new T[n];
  7. if (_start)//start不为为空
  8. {
  9. //memcpy(tmp, _start, sz*sizeof(T));
  10. for (size_t i = 0; i << sz; i++)
  11. {
  12. tmp[i] = _start[i];
  13. }
  14. delete[] _start;
  15. }
  16. _start = tmp;
  17. _finish = _start+sz;//finish还为0,start新空间,size()会返回很大的负值
  18. _endofstorage=_start+n;//endofstorage还为0,start新空间,capacity()会返回很大的负值
  19. }
  20. }
  21. void resize(size_t n, T val = T())
  22. {
  23. if (n < size())
  24. {
  25. _finish = _start + n;
  26. }
  27. else
  28. {
  29. if (n > capacity())
  30. {
  31. reserve(n);
  32. }
  33. for (size_t i = size(); i < n; i++)
  34. {
  35. *_finish = val;
  36. _finish++;
  37. }
  38. }
  39. }

                4.拷贝构造函数和赋值运算符重载

  • 拷贝构造注意深层次的深浅拷贝;
  • 赋值运算符重载现代写法思想:传值传参,交换之后,因为v是临时对象,出函数生命周期结束,那么会释放交换后的数组;   
  1. vector(const vector<T>& v)//拷贝构造
  2. :_start(nullptr)
  3. ,_finish(nullptr)
  4. ,_endofstorage(nullptr)
  5. {
  6. _start = new T[v.capacity()];
  7. /*memcpy(_start, v._start, sizeof(T) * v.capacity());*/
  8. for (size_t i = 0; i < v.size(); i++)//解决深层次的深浅拷贝
  9. {
  10. _start[i] = v._start[i];
  11. }
  12. _endofstorage = _start + v.capacity();
  13. _finish = _start + v.size();
  14. }
  15. vector<T>& operator=(vector<T> v)
  16. {
  17. swap(_start, v._start);
  18. swap(_finish, v._finish);
  19. swap(_endofstorage, v._endofstorage);
  20. return *this;
  21. }

                5.插入和删除 

  • insert增容后注意更新一下pos,防止迭代器失效;
  1. void push_back(const T& x)
  2. {
  3. if (_finish == _endofstorage)
  4. {
  5. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
  6. reserve(newCapacity);
  7. }
  8. *_finish = x;
  9. _finish++;
  10. }
  11. void pop_back()
  12. {
  13. assert(!empty());
  14. --_finish;
  15. }
  16. void insert(iterator pos, const T& x)
  17. {
  18. size_t sz = pos - _start;
  19. if (_finish == _endofstorage)//判断增容
  20. {
  21. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
  22. reserve(newCapacity);
  23. //更新pos,防止迭代器失效
  24. pos = _start + sz;
  25. }
  26. iterator end = _finish - 1;
  27. while (end >= pos)
  28. {
  29. *(end + 1) = *end;
  30. --end;
  31. }
  32. *end = x;
  33. ++_finish;
  34. }
  35. iterator erase(iterator pos)
  36. {
  37. iterator it = pos + 1;
  38. while (it != end())
  39. {
  40. *(it - 1) = *it;
  41. ++it;
  42. }
  43. _finish--;
  44. return pos;
  45. }

                全部代码

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<assert.h>
  4. #include<string>
  5. using namespace std;
  6. namespace lj
  7. {
  8. template<class T>
  9. class vector
  10. {
  11. public:
  12. typedef T* iterator;
  13. typedef const T* const_iterator;
  14. const_iterator begin()const
  15. {
  16. return _start;
  17. }
  18. const_iterator end()const
  19. {
  20. return _finish;
  21. }
  22. iterator begin()
  23. {
  24. return _start;
  25. }
  26. iterator end()
  27. {
  28. return _finish;
  29. }
  30. vector()
  31. :_start(nullptr)
  32. ,_finish(nullptr)
  33. ,_endofstorage(nullptr)
  34. {}
  35. // 类模板的成员函数,还可以再是函数模板
  36. template<class InputIterator>
  37. vector(InputIterator first, InputIterator last)
  38. : _start(nullptr)
  39. , _finish(nullptr)
  40. , _endofstorage(nullptr)
  41. {
  42. while (first != last)
  43. {
  44. push_back(*first);
  45. ++first;
  46. }
  47. }
  48. ~vector()
  49. {
  50. if (_start)
  51. {
  52. delete[] _start;
  53. _start = _finish = _endofstorage = nullptr;
  54. }
  55. }
  56. vector(const vector<T>& v)//拷贝构造
  57. :_start(nullptr)
  58. ,_finish(nullptr)
  59. ,_endofstorage(nullptr)
  60. {
  61. _start = new T[v.capacity()];
  62. /*memcpy(_start, v._start, sizeof(T) * v.capacity());*/
  63. for (size_t i = 0; i < v.size(); i++)//解决深层次的深浅拷贝
  64. {
  65. _start[i] = v._start[i];
  66. }
  67. _endofstorage = _start + v.capacity();
  68. _finish = _start + v.size();
  69. }
  70. vector<T>& operator=(vector<T> v)
  71. {
  72. swap(_start, v._start);
  73. swap(_finish, v._finish);
  74. swap(_endofstorage, v._endofstorage);
  75. return *this;
  76. }
  77. /*vector<T>& operator=(const vector<T>& v)
  78. {
  79. if(_start!=v._start)
  80. {
  81. delete[] _start;
  82. _start = new T[v.capacity()];
  83. memcpy(_start, v._start, sizeof(T) * v.capacity());
  84. _endofstorage = _start + v.capacity();
  85. _finish = _start + v.size();
  86. }
  87. return *this;
  88. }*/
  89. size_t size()const
  90. {
  91. return _finish - _start;
  92. }
  93. size_t capacity()const
  94. {
  95. return _endofstorage - _start;
  96. }
  97. void reserve(size_t n)
  98. {
  99. if (n > capacity())
  100. {
  101. size_t sz = size();
  102. iterator tmp = new T[n];
  103. if (_start)//start不为为空
  104. {
  105. //memcpy(tmp, _start, sz*sizeof(T));
  106. for (size_t i = 0; i << sz; i++)
  107. {
  108. tmp[i] = _start[i];
  109. }
  110. delete[] _start;
  111. }
  112. _start = tmp;
  113. _finish = _start+sz;//finish还为0,start新空间,size()会返回很大的负值
  114. _endofstorage=_start+n;//endofstorage还为0,start新空间,capacity()会返回很大的负值
  115. }
  116. }
  117. void resize(size_t n, T val = T())
  118. {
  119. if (n < size())
  120. {
  121. _finish = _start + n;
  122. }
  123. else
  124. {
  125. if (n > capacity())
  126. {
  127. reserve(n);
  128. }
  129. for (size_t i = size(); i < n; i++)
  130. {
  131. *_finish = val;
  132. _finish++;
  133. }
  134. }
  135. }
  136. bool empty()
  137. {
  138. return _start == _finish;
  139. }
  140. void push_back(const T& x)
  141. {
  142. if (_finish == _endofstorage)
  143. {
  144. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
  145. reserve(newCapacity);
  146. }
  147. *_finish = x;
  148. _finish++;
  149. }
  150. void pop_back()
  151. {
  152. assert(!empty());
  153. --_finish;
  154. }
  155. void insert(iterator pos, const T& x)
  156. {
  157. size_t sz = pos - _start;
  158. if (_finish == _endofstorage)//判断增容
  159. {
  160. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
  161. reserve(newCapacity);
  162. //更新pos,防止迭代器失效
  163. pos = _start + sz;
  164. }
  165. iterator end = _finish - 1;
  166. while (end >= pos)
  167. {
  168. *(end + 1) = *end;
  169. --end;
  170. }
  171. *end = x;
  172. ++_finish;
  173. }
  174. iterator erase(iterator pos)
  175. {
  176. iterator it = pos + 1;
  177. while (it != end())
  178. {
  179. *(it - 1) = *it;
  180. ++it;
  181. }
  182. _finish--;
  183. return pos;
  184. }
  185. void PrintVector()const
  186. {
  187. vector<T>::const_iterator it = this->begin();
  188. while (it != this->end())
  189. {
  190. //*it += 1;//只能读,不能写
  191. cout << *it << " ";
  192. ++it;
  193. }
  194. cout << endl;
  195. }
  196. private:
  197. iterator _start;
  198. iterator _finish;
  199. iterator _endofstorage;
  200. };
  201. void test_vector1()
  202. {
  203. vector<int> v;
  204. v.push_back(1);
  205. v.push_back(2);
  206. v.push_back(3);
  207. v.push_back(4);
  208. v.push_back(5);
  209. v.push_back(6);
  210. vector<int>::iterator it = v.begin();
  211. while (it != v.end())
  212. {
  213. cout << *it << " ";
  214. ++it;
  215. }
  216. cout << endl;
  217. v.PrintVector();
  218. }
  219. void test_vector2()
  220. {
  221. vector<int> v;
  222. v.push_back(1);
  223. v.push_back(2);
  224. v.push_back(3);
  225. v.push_back(4);
  226. v.push_back(5);
  227. v.push_back(6);
  228. //v.pop_back();
  229. v.resize(3);
  230. v.resize(6,1);
  231. v.resize(12,2);
  232. vector<int>::iterator it = v.begin();
  233. while (it != v.end())
  234. {
  235. cout << *it << " ";
  236. ++it;
  237. }
  238. cout << endl;
  239. }
  240. void test_vector3()
  241. {
  242. vector<int> v;
  243. v.push_back(1);
  244. v.push_back(2);
  245. v.push_back(3);
  246. v.push_back(4);
  247. v.push_back(5);
  248. v.push_back(6);
  249. vector<int>::iterator pos = find(v.begin(), v.end(), 3);
  250. v.insert(pos, 30);
  251. v.PrintVector();
  252. }
  253. void test_vector4()
  254. {
  255. vector<int> v;
  256. v.push_back(1);
  257. v.push_back(2);
  258. v.push_back(3);
  259. v.push_back(4);
  260. v.push_back(5);
  261. v.push_back(6);
  262. vector<int>::iterator pos = find(v.begin(), v.end(), 3);
  263. v.erase(pos);
  264. v.PrintVector();
  265. }
  266. void test_vector5()
  267. {
  268. vector<int> v;
  269. v.push_back(1);
  270. v.push_back(2);
  271. v.push_back(3);
  272. vector<int> v1(v);
  273. vector<int> v2;
  274. v1=v2=v;
  275. v.PrintVector();
  276. v1.PrintVector();
  277. v2.PrintVector();
  278. }
  279. void test_vector6()
  280. {
  281. vector<string> v;
  282. v.push_back("111111111111111111");
  283. v.push_back("2222");
  284. v.push_back("3333");
  285. v.push_back("4444");
  286. v.push_back("5555");
  287. vector<string> v1(v);
  288. v.PrintVector();
  289. v1.PrintVector();
  290. }
  291. }
  292. int main()
  293. {
  294. //lj::test_vector1();
  295. //lj::test_vector2();
  296. //lj::test_vector3();
  297. lj::test_vector6();
  298. return 0;
  299. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/452725
推荐阅读
相关标签
  

闽ICP备14008679号