vector的简单实现

功能尚不完全, 存在缺陷。定义Vector<int> vec(10, 10)会报出异常, 原因是无法识别10是int型还是iterator型。

注意几点:

分配内存不要使用new和delete,因为new的同时就把对象构造了,而我们需要的是原始内存。

所以应该使用标准库提供的allocator类来实现内存的控制。当然也可以重载operator new操作符,因为二者都是使用malloc作为底层实现,所以直接采用malloc也可以。

对象的复制必须使用系统提供的uninitialized_fill和uninitialized_copy,因为我们无法手工调用构造函数。

对于C++中的对象,除了POD之外,使用memcpy系列的函数是绝对错误的。

代码如下:

  1 #ifndef VECTOR_H
  2 #define VECTOR_H
  3
  4 #include <memory>
  5 #include <algorithm>
  6 #include <stddef.h>
  7 #include <limits>
  8 template <typename T, typename Alloc>
  9 class Vector;
 10
 11 template <typename T, typename Alloc>
 12 bool operator== (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 13 template <typename T, typename Alloc>
 14 bool operator!= (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 15 template <typename T, typename Alloc>
 16 bool operator> (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 17 template <typename T, typename Alloc>
 18 bool operator>= (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 19 template <typename T, typename Alloc>
 20 bool operator< (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 21 template <typename T, typename Alloc>
 22 bool operator<= (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 23
 24
 25 template <typename T, typename Alloc = std::allocator<T> >
 26 class Vector
 27 {
 28     friend bool operator==<T, Alloc> (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 29     friend bool operator!=<T, Alloc> (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 30     friend bool operator> <T, Alloc> (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 31     friend bool operator>=<T, Alloc> (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 32     friend bool operator< <T, Alloc> (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 33     friend bool operator<=<T, Alloc> (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b);
 34
 35     class reverse_iterator;
 36     class const_reverse_iterator;
 37 public:
 38     typedef T value_type;
 39     typedef T *iterator;
 40     typedef const T *const_iterator;
 41     typedef reverse_iterator reverse_iterator;
 42     typedef const_reverse_iterator const_reverse_iterator;
 43     typedef T &reference;
 44     typedef const T &const_reference;
 45     typedef T *pointer;
 46     typedef const T *const_pointer;
 47     typedef size_t size_type;
 48     typedef ptrdiff_t difference_type;
 49     typedef Alloc allocator_type;
 50 private:
 51     //逆序迭代器
 52     class reverse_iterator
 53     {
 54     public:
 55         reverse_iterator(iterator it = NULL) :_current(it) { }
 56         iterator base() const {return _current; }
 57         reverse_iterator &operator++ ()
 58         {
 59             -- _current;
 60             return *this;
 61         }
 62         reverse_iterator operator++ (int)
 63         {
 64             reverse_iterator tmp(*this);
 65             -- _current;
 66             return tmp;
 67         }
 68         reverse_iterator &operator-- ()
 69         {
 70             ++ _current;
 71             return *this;
 72         }
 73         reverse_iterator operator-- (int)
 74         {
 75             reverse_iterator tmp(*this);
 76             ++ _current;
 77             return tmp;
 78         }
 79
 80         reference operator*()
 81         {
 82             return *(_current - 1);
 83         }
 84
 85         const_reference operator*() const
 86         {
 87             return *(_current - 1);
 88         }
 89
 90         pointer operator-> ()
 91         { return _current - 1; }
 92
 93         const_pointer operator-> () const
 94         { return _current - 1; }
 95
 96         friend bool operator== (reverse_iterator i,
 97                                 reverse_iterator j)
 98         {
 99             return i._current == j._current;
100         }
101
102         friend bool operator!= (reverse_iterator i,
103                                 reverse_iterator j)
104         {
105             return i._current != j._current;
106         }
107
108
109         friend difference_type operator-(reverse_iterator i,
110                                          reverse_iterator j)
111         {
112             return i._current - j._current;
113         }
114     private:
115             iterator _current;
116     };
117     //逆序迭代器
118
119
120     //const逆序迭代器
121     class const_reverse_iterator
122     {
123     public:
124         const_reverse_iterator(const_iterator it = NULL) :_current(it) { }
125         const_reverse_iterator(reverse_iterator it) :_current(it.base()) { }
126         const_iterator base() const {return _current; }
127         const_reverse_iterator &operator++ ()
128         {
129             -- _current;
130             return *this;
131         }
132         const_reverse_iterator operator++ (int)
133         {
134             reverse_iterator tmp(*this);
135             -- _current;
136             return tmp;
137         }
138         const_reverse_iterator &operator-- ()
139         {
140             ++ _current;
141             return *this;
142         }
143         const_reverse_iterator operator-- (int)
144         {
145             reverse_iterator tmp(*this);
146             ++ _current;
147             return tmp;
148         }
149
150         const_reference operator*() const
151         {
152             return *(_current - 1);
153         }
154
155
156         const_pointer operator-> () const
157         { return _current - 1; }
158
159         friend bool operator== (const_reverse_iterator i,
160                                 const_reverse_iterator j)
161         {
162             return i._current == j._current;
163         }
164
165         friend bool operator!= (const_reverse_iterator i,
166                                 const_reverse_iterator j)
167         {
168             return i._current != j._current;
169         }
170
171
172         friend difference_type operator-(const_reverse_iterator i,
173                                          const_reverse_iterator j)
174         {
175             return i._current - j._current;
176         }
177     private:
178             const_iterator _current;
179     };
180     //const逆序迭代器
181
182
183
184 public:
185     //三种构造Vector的方法
186     Vector() { create(); }
187
188     explicit Vector(size_type n, const value_type &val = value_type())
189     { create(n, val); }
190
191     template <typename In>
192     Vector(In i, In j)
193     { create(i, j); }
194
195     //复制v对象
196     Vector(const Vector &v)
197     { create(v.begin(), v.end()); }
198     //赋值函数
199     Vector &operator= (const Vector &v);
200     //析构函数
201     ~Vector() { uncreate(); }
202     //assign操作的几种形式
203     template <typename In>
204     void assign(In i, In j)
205     {
206         uncreate();
207         create(i, j);
208     }
209
210     void assign(size_type n, const T &val)
211     {
212         uncreate();
213         create(n, val);
214     }
215     //下标操作
216     reference operator[] (size_type index) { return _data[index]; }
217     const_reference operator[] (size_type index) const { return _data[index]; }
218     //at操作
219     reference at(size_type index) { return _data[index]; }
220     const_reference at(size_type index) const { return _data[index]; }
221     //front、back操作
222     reference front() { return *begin(); }
223     reference back() { return *rbegin(); }
224     const_reference front() const { return *begin(); }
225     const_reference back() const { return *rbegin(); }
226
227     //pop_back操作
228     void pop_back()
229     { _alloc.destroy(-- _avail); }
230     //insert函数的几种操作
231     iterator insert (iterator pos, const value_type &val);
232
233     void insert(iterator pos, size_type n, const value_type &val);
234
235     template <typename InputIterator>
236     void insert(iterator pos, InputIterator first, InputIterator last);
237
238     //erase的几种操作
239     iterator erase(iterator pos);
240
241     iterator erase(iterator first, iterator last);
242
243
244     //resize和reserve的操作
245     void resize(size_type n, value_type val = value_type());
246     void reserve(size_type n);
247
248     //判断是否为空、查看元素个数、查看空间大小
249     bool empty() const { return _data == _avail; }
250     size_type size() const { return _avail - _data; }
251
252     size_type capacity() const { return _limit - _data; }
253
254     size_type max_size() const
255     { return std::numeric_limits<size_type>::max() / sizeof(T); }
256     //begin、end迭代器操作
257     iterator begin() { return _data; }
258     const_iterator begin() const { return _data; }
259
260     iterator end() { return _avail; }
261     const_iterator end() const { return _avail; }
262
263     //rbegin、rend迭代器操作
264     reverse_iterator rbegin() { return reverse_iterator(_avail); }
265     reverse_iterator rend() { return reverse_iterator(_data); }
266
267     const_reverse_iterator rbegin() const { return const_reverse_iterator(_avail); }
268     const_reverse_iterator rend() const { return const_reverse_iterator(_data); }
269     //push_back操作
270     void push_back(const T &t)
271     {
272         if(_avail == _limit)
273             grow();
274         unCheckdAppend(t);
275     }
276
277     //与other对象进行交换
278     void swap(Vector &other)
279     {
280         std::swap(_data, other._data);
281         std::swap(_avail, other._avail);
282         std::swap(_limit, other._limit);
283     }
284     //
285     allocator_type get_allocator() const
286     { return _alloc; }
287
288
289 private:
290     iterator _data;             //数组首元素
291     iterator _avail;            //数组最后一个元素的下一个位置
292     iterator _limit;            //最后一块内存的下一块位置
293
294     std::allocator<T> _alloc;   //内存分配器
295
296
297     void create();
298     void create(size_type, const value_type &);
299
300     template <typename In>
301     void create(In i, In j);
302
303
304     void uncreate();
305
306     void grow();            //内存增长
307     void unCheckdAppend(const T &val);
308
309     void growTon(size_type n);
310 };
311 //复制构造函数
312 template <typename T, typename Alloc>
313 Vector<T, Alloc> &Vector<T, Alloc>::operator= (const Vector &v)
314 {
315     if(this != &v)
316     {
317         uncreate();
318         create(v.begin(), v.end());
319     }
320
321     return *this;
322 }
323
324
325 //三个构造函数
326 template <typename T, typename Alloc>
327 void Vector<T,Alloc>::create()
328 {
329     _data = _avail = _limit = NULL;
330 }
331
332
333 template <typename T, typename Alloc>
334 void Vector<T, Alloc>::create(size_type n, const T &val)
335 {
336     //先分配内存
337     _data = _alloc.allocate(n);
338     //初始化赋值
339     std::uninitialized_fill(_data, _data + n, val);
340     _avail = _limit = _data + n;
341 }
342
343
344 template <typename T, typename Alloc>
345 template <typename In>
346 void Vector<T, Alloc>::create(In i, In j)
347 {
348     _data = _alloc.allocate(j - i);
349
350     _avail = _limit = std::uninitialized_copy(i, j, _data);
351
352 }
353
354
355 //析构函数
356 template <typename T, typename Alloc>
357 void Vector<T, Alloc>::uncreate()
358 {
359     //先执行析构函数
360     if(_data)
361     {
362         iterator it(_avail);
363         while(it != _data)
364         {
365             _alloc.destroy(-- it);
366         }
367     }
368
369     //释放内存
370     _alloc.deallocate(_data, _limit - _data);
371     _data = _avail = _limit = NULL;
372 }
373
374
375
376 //grow函数
377 template <typename T, typename Alloc>
378 void Vector<T, Alloc>::grow()
379 {
380     //确定size
381     size_type new_size = std::max(2 * (_limit - _data), difference_type(1));
382
383     growTon(new_size);
384 }
385
386
387 //unCheckdAppend函数
388 template <typename T, typename Alloc>
389 void Vector<T, Alloc>::unCheckdAppend(const T &val)
390 {
391     _alloc.construct(_avail ++, val);
392 }
393
394
395 //growTon函数
396 template <typename T, typename Alloc>
397 void Vector<T, Alloc>::growTon(size_type n)
398 {
399     iterator new_data = _alloc.allocate(n);
400     iterator new_avail = std::uninitialized_copy(_data, _avail, new_data);
401
402     uncreate();
403
404     _data = new_data;
405     _avail = new_avail;
406     _limit = _data + n;
407 }
408
409
410 //insert函数
411
412 template <typename T, typename Alloc>
413 typename Vector<T, Alloc>::iterator Vector<T, Alloc>::insert(iterator pos, const value_type &val)
414 {
415     difference_type i = pos - _data;
416     insert(pos, 1, val);
417     return pos + i;
418 }
419
420
421 template <typename T, typename Alloc>
422 void Vector<T, Alloc>::insert(iterator pos, size_type n, const value_type &val)
423 {
424     difference_type i = pos - _data;
425     while(static_cast<size_type>(_limit - _avail) < n)
426         grow();
427     pos = _data + i;
428
429     size_type left = _avail - pos;
430
431     if(n < left)
432     {
433         size_type len = _avail - pos;
434         size_type copyLen = len - n;
435         std::uninitialized_copy(pos + copyLen, _avail, _avail);
436         std::copy_backward(pos, pos + copyLen, _avail);
437
438         std::fill_n(pos, n, val);
439     }
440     else if(n > left)
441     {
442         std::uninitialized_copy(pos, _avail, pos + n);
443
444         std::fill_n(pos, _avail - pos, val);
445         std::uninitialized_fill(_avail, pos + n, val);
446     }
447     else
448     {
449         std::uninitialized_copy(pos, _avail, _avail);
450         std::fill_n(pos, n, val);
451     }
452
453     _avail = _avail + n;
454 }
455
456 template <typename T, typename Alloc>
457 template <typename InputIterator>
458 void Vector<T, Alloc>::insert(iterator pos, InputIterator first, InputIterator last)
459 {
460     difference_type i = pos - _data;
461     size_type n = last - first;
462     while(static_cast<size_type>(_limit - _avail) < n)
463         grow();
464     pos = _data + i;
465
466     size_type left = _avail - pos;
467     if(n < left)
468     {
469         size_type len = _avail - pos;
470         size_type copyLen = len - n;
471         std::uninitialized_copy(pos + copyLen, _avail, _avail);
472         std::copy_backward(pos, pos + copyLen, _avail);
473
474         std::copy(first, last, pos);
475     }
476     else if(n > left)
477     {
478         std::uninitialized_copy(pos, _avail, pos + n);
479
480         std::copy(first, first + left, pos);
481         std::uninitialized_copy(first + left, last, _avail);
482     }
483     else
484     {
485         std::uninitialized_copy(pos, _avail, _avail);
486
487         std::copy(first, last, pos);
488     }
489
490     _avail = _avail + n;
491 }
492
493
494 //erase函数
495
496 template <typename T, typename Alloc>
497 typename Vector<T, Alloc>::iterator Vector<T, Alloc>::erase(iterator pos)
498 {
499     std::copy(pos + 1, _avail, pos);
500     _alloc.destroy(-- _avail);
501     return pos;
502 }
503
504 template <typename T, typename Alloc>
505 typename Vector<T, Alloc>::iterator Vector<T, Alloc>::erase(iterator first, iterator last)
506 {
507     difference_type left = _avail - last;
508     std::copy(last, _avail, first);
509
510     iterator it(first + left);
511     while(_avail != it)
512         _alloc.destroy(-- _avail);
513     return first;
514 }
515
516
517 //resize函数
518 template <typename T, typename Alloc>
519 void Vector<T, Alloc>::resize(size_type n, value_type val)
520 {
521     size_type cur_size = size();
522     if(n < cur_size)
523     {
524         size_type diff = cur_size - n;
525         while(diff --)
526             _alloc.destroy(-- _avail);
527     }
528     else if(n > cur_size)
529     {
530         size_type diff = n - cur_size;
531         size_type left = static_cast<size_type>(_limit - _avail);
532         if(left < diff)
533             growTon(n);
534
535         while(size() < n)
536             unCheckdAppend(val);
537     }
538 }
539
540 template <typename T, typename Alloc>
541 void Vector<T, Alloc>::reserve(size_type n)
542 {
543     size_type cur_cap = capacity();
544     if(n > cur_cap)
545         growTon(n);
546 }
547
548
549 //运算符重载
550 template <typename T, typename Alloc>
551 bool operator== (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b)
552 {
553     return a.size() == b.size() &&
554            std::equal(a.begin(), a.end(), b.begin() );
555 }
556
557
558 template <typename T, typename Alloc>
559 bool operator!= (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b)
560 {
561     return !(a == b);
562 }
563
564
565 template <typename T, typename Alloc>
566 bool operator< (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b)
567 {
568     typedef typename Vector<T, Alloc>::size_type size_type;
569     size_type size1 = a.size();
570     size_type size2 = b.size();
571     size_type min =(size1 < size2) ? size1 : size2;
572     size_type i = 0;
573     for(; i != min; ++ i)
574     {
575         if(a[i] < b[i])
576             return true;
577         else if(a[i] > b[i])
578             return false;
579     }
580     if(i != size2)
581         return true;
582     return false;
583 }
584
585
586 template <typename T, typename Alloc>
587 bool operator<= (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b)
588 {
589     return !(a > b);
590 }
591
592
593 template <typename T, typename Alloc>
594 bool operator> (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b)
595 {
596     return b < a;
597 }
598
599
600 template <typename T, typename Alloc>
601 bool operator>= (const Vector<T, Alloc> &a, const Vector<T, Alloc> &b)
602 {
603     return !(a < b);
604 }
605
606
607 #endif  /*VECTOR_H*/

测试代码如下:

 1 #include "Vector.hpp"
 2 #include <iostream>
 3 #include <string>
 4 using namespace std;
 5
 6 //测试const reverse迭代器
 7 void print(const Vector<string> &vec)
 8 {
 9     for(Vector<string>::const_reverse_iterator it = vec.rbegin();
10         it != vec.rend();
11         ++it)
12     {
13         cout << *it << " ";
14     }
15     cout << endl;
16 }
17
18 int main(int argc, char const *argv[])
19 {
20     Vector<string> vec(3, "hello");
21
22     for(Vector<string>::const_iterator it = vec.begin();
23         it != vec.end();
24         ++it)
25     {
26         cout << *it << " ";
27     }
28     cout << endl;
29
30     cout << "size = " << vec.size() << endl;
31     cout << "capacity = " << vec.capacity() << endl;
32     vec.push_back("foo");
33     vec.push_back("bar");
34
35     cout << "size = " << vec.size() << endl;
36     cout << "capacity = " << vec.capacity() << endl;
37
38     for(Vector<string>::reverse_iterator it = vec.rbegin();
39         it != vec.rend();
40         ++it)
41     {
42         cout << *it << " ";
43     }
44     cout << endl;
45
46
47     print(vec);
48
49     Vector<string> vec2;
50     vec2.push_back("beijing");
51     vec2.push_back("shanghai");
52     vec2.push_back("guangzhou");
53     print(vec2);
54
55     vec.swap(vec2);
56     print(vec);
57     print(vec2);
58
59     return 0;
60 }
时间: 2024-10-05 07:54:10

vector的简单实现的相关文章

set 和 vector的简单比较

set的常见问题(转) (1)为何map和set的插入删除效率比用其他序列容器高? 大部分人说,很简单,因为对于关联容器来说,不需要做内存拷贝和内存移动.说对了,确实如此.set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点.结构图可能如下: A   / \ B C / \ / \   D E F G 因此插入的时候只需要稍做变换,把节点的指针指向新的节点就可以了.删除的时候类似,稍做变换后把指向删除节点的指针指向其他节点也OK了.这里的一切操作就是指针换来换去

STL vector的简单实现

STL中的Vector相对关联容器来说比较容易实现,其实际上就是一个动态数组的概念.此代码只实现了类的几个简单的功能,因为Vector的迭代器比较特殊(其实就是×T)故而此处的代码也很简略.代码如下: #include<iostream> using namespace std; template<class T> class myVector{ public: typedef T value_type; typedef value_type* iterator; myVector

C++--VECTOR的简单应用

在c++中,vector是一个十分有用的容器,下面对这个容器做一下总结. 1 基本操作 (1)头文件#include<vector>. (2)创建vector对象,vector<int> vec; (3)尾部插入数字:vec.push_back(a); (4)使用下标访问元素,cout<<vec[0]<<endl;记住下标是从0开始的. (5)使用迭代器访问元素. vector<int>::iterator it; for(it=vec.begi

STL vector的简单用法

 <span style="font-size:18px;">STL中的vector实际上是一种称为动态表的数据结构.所谓动态表,是指一种能够自动扩张和收缩的表.在开始的时候动态表预先分配一块连续的存储空间,将表中的元素存储在这块连续的空间内:如果不断地向表中插入元素,最终原来的那块存储空间可能会不够用,这时候动态表就会自动分配一块更大的存储空间,并将表中原来的元素全部复制到这块较大的空间内.</span> <span style="font

STL学习篇:vector的简单使用

vector,一个动态数组!在堆中操作,元素连续存放,可以直接访问其中的任何元素,初始分配有内存,当保留内存不够的时候,会再分配内存! 下面看一个vector的构造函数例子: 1 #include <iostream> 2 #include<vector> 3 #include<string> 4 5 int main() 6 { 7 using namespace std; 8 9 //类模板,模板参数 10 vector<int> ivec;//保存in

vector容器简单例子

STL六大组件:容器,算法迭代器,空间配置器,适配器,仿函数 vector容器:连续的存储空间,双向,随机,单口容器,只能在一端进行插入删除 例子: #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> using namespace std; void printVector(const vector<int> &bmw) { for (vector<int>::co

CUP对内存管理精华总(vector机制)

CPU对内存管理一: 内存:电容 操作系统:管理内存 CPU:处理数据. PC的CPU位数决定安装的操作系统位数,大了,浪费,小了无法安装操作系统 未来移动方向CPU与操作系统的最佳组合是Inter和微软 → 软件的沉淀 CPU对内存管理二: 内存4G用切割32位的方法划分为页表 页表和物理内存对应 优点:物理内存的保护和节省内存 一般认识的缺陷:可用内存4G,实际为少1M,一级页表 CPU对内存管理三: vector原理: 使用的内存,在页表中预留填写-1 -1提交后填写物理内存地址 使用完后

Android Drawable Mipmap Vector使用及Vector兼容

原文地址:http://blog.csdn.net/eclipsexys/article/details/51838119 http://blog.csdn.net/qq_15545283/article/details/51472458 一.谷歌在app中图标的适配的历史 在安卓的发展历程中,由于设备碎片化的原故,谷歌在app中图标的适配上做出一步又一步的改进,大体有这么几个阶段: 首先有了drawable-(m|h|xh|xxh|xxxh)dpi 自android studio后,又有了mi

给jdk写注释系列之jdk1.6容器(10)-Stack&amp;Vector源码解析

前面我们已经接触过几种数据结构了,有数组.链表.Hash表.红黑树(二叉查询树),今天再来看另外一种数据结构:栈. 什么是栈呢,我就不找它具体的定义了,直接举个例子,栈就相当于一个很窄的木桶,我们往木桶里放东西,往外拿东西时会发现,我们最开始放的东西在最底部,最先拿出来的是刚刚放进去的.所以,栈就是这么一种先进后出( First In Last Out,或者叫后进先出) 的容器,它只有一个口,在这个口放入元素,也在这个口取出元素. 栈最主要了两个动作就是入栈和出栈操作,其实还是很容易的明白的对不