Vector.h
#pragma once #include "Alloc.h" #include "Uninitialized.h" #include <assert.h> //vector采用的数据结构就是线性连续空间 template<class T,class Alloc = alloc> class Vector { public: //嵌套型别 typedef T* Iterator; typedef T ValueType; typedef T* Pointer; typedef T& Reference; typedef ptrdiff_t DifferenceType; typedef const T* ConstPointer; typedef const T* ConstIterator; typedef const T& ConstReference; protected: typedef SimpleAlloc<ValueType, Alloc> DataAllocator; typedef Vector<T> Self; T* _start; //表示目前使用空间的头 T* _end; //表示目前使用空间的尾 T* _endOfStorage;//表示目前可用空间的尾 public: Vector() :_start(NULL) , _end(NULL) , _endOfStorage(NULL) {} Vector(size_t n, const T& value)//构造函数,指定Vector大小并填充初值 { FillInitializen(n, value); } void FillInitializen(size_t n,const T& value) { _start = AllocateAndFill(n,value); _end = _start + n; _endOfStorage = _end; } Iterator AllocateAndFill(size_t n,const T& value) { Iterator result = DataAllocator::Allocate(n);//分配空间 //UninitializedFill(result,n,value); return result; } ~Vector() {} Iterator Begin() { return _start; } ConstIterator Begin()const { return _start; } Iterator End() { return _end; } ConstIterator End()const { return _end; } Reference Front() { return *Begin(); } ConstReference Front()const { return *Begin(); } Reference Back() { return *(End() - 1); } ConstReference Back()const { return *(End() - 1); } void PushBack(const T& x) { Insert(End(),x); } void PopBack() { if (_start != _end){ --_end;//表示放弃尾部元素 Destroy(_end); } } //iterator insert(iterator position); //iterator insert(iterator position, const T& x); //void insert(iterator position, InputIterator first, InputIterator last); //void insert(iterator position,const_iterator first, const_iterator last); //void insert(iterator pos, size_type n, const T& x); //void insert(iterator pos, int n, const T& x); //void insert(iterator pos, long n, const T& x); Iterator Insert(Iterator pos,const T& x) { //以下配置原则:如果原大小为0,则配置1个元素的大小 // 否则,配置原大小的两倍 size_t n = pos - _start; size_t oldsize = Size(); if (_start == _endOfStorage){//1、此时没有一个数据,可用空间为0,需要扩容 //_start = new T(x); _start = DataAllocator::Allocate();// Construct(_start,x); //new(_start)ValueType(x); _end = _start + 1; _endOfStorage = _end; } else if (pos == End() && _end < _endOfStorage){//2、尾插且不需要扩容 _start[oldsize] = x; ++_end; } else{ //3、非尾插 _CheckEndOfStorage(); Iterator tmp = _end; pos = _start + n;//**************** very importent 有可能扩容,pos就不是要插入的那个位置了 while (pos <= tmp){ *(tmp + 1) = *tmp; --tmp; } *pos = x; ++_end; } return _start+n; } //Iterator Erase(Iterator first,Iterator last); Iterator Erase(Iterator pos) { assert(pos != End()); size_t size = Size(); if (size == 0){ return pos; } size_t n = pos - _start; Iterator tmp = pos; while (tmp < End()-1){ *tmp = *(tmp + 1); tmp++; } _end--; *_end = ValueType(); return _start + n; } bool Empty() { return Begin()==End(); } size_t Size() { return _end - _start; } Reference operator[](size_t index) { assert(index >= 0 && index < Size()); return *(Begin() + index); } ConstReference operator[](size_t index)const { assert(index >= 0 && index < Size()); return *(Begin() + index); } //void resize(size_type sz, T c = T()); //void reserve(size_type n); //Reference At(const size_t i); //void Swap(Self& x); //void Clear(); private: void _CheckEndOfStorage() { int oldcapacity = Size(); if (_start != NULL && _end < _endOfStorage){ return; } int newcapacity = oldcapacity * 2 ; /*//1. T* tmp = new T[newcapacity]; int index = 0; while (index < oldcapacity){ tmp[index] = _start[index]; index++; } if (oldcapacity == 1) delete _start; else delete[] _start;//如果只有一个空间用delete _start; _start = tmp; _end = _start + oldcapacity; _endOfStorage = _start + newcapacity;*/ /*//2. T* tmp = DataAllocator::Allocate(newcapacity); int index = 0; while (index < oldcapacity){ tmp[index] = _start[index]; index++; } index = 0; while (index < oldcapacity){ (&_start[index])->~T(); index++; } DataAllocator::Deallocate(&_start[index], oldcapacity); _start = tmp; _end = _start + oldcapacity; _endOfStorage = _start + newcapacity;*/ //3. T* tmp = DataAllocator::Allocate(newcapacity); UninitializedCopy(_start, _end, tmp); Destroy(_start, _end); DataAllocator::Deallocate(_start, oldcapacity); _start = tmp; _end = _start + oldcapacity; _endOfStorage = _start + newcapacity; } };
Test.cpp
#include "Vector.h" #include <vector> void printVector2(Vector<int> v) { size_t size = v.Size(); Vector<int>::Iterator it = v.Begin(); while (it!=v.End()){ std::cout << *it << std::endl; ++it; } } void printvector1(std::vector<int> v) { size_t size = v.size(); std::vector<int>::iterator it = v.begin(); while (it != v.end()){ std::cout << *it << std::endl; ++it; } } void TestVector() { //std::vector<int> v1; //v1.push_back(2); //std::vector<int>::iterator item; //item=v1.Begin(); ////v1.erase(item); ////v1.pop_back(); //printvector1(v1); Vector<int> v2; v2.PushBack(2); Vector<int>::Iterator ite; ite = v2.Begin(); v2.Erase(ite); printVector2(v2); v2.PopBack(); v2.PushBack(1); v2.PushBack(2); v2.PushBack(3); v2.PushBack(4); v2.PopBack(); std::cout<<v2[0]<<std::endl; printVector2(v2); //ite = v2.end(); //v2.erase(ite); //printvector2(v2); /*ite = v2.Begin(); v2.insert(ite,5); printvector2(v2); v2.erase(ite); ite = v2.Begin(); printvector2(v2);*/ /*ite = v2.end(); v2.erase(ite);*/ //printvector2(v2); }
vector还有两个函数 reserve()和resize()
分别是改变capacity和改变size
vector 的reserve增加了vector的capacity,但是它的size没有改变!而resize改变了vector的capacity同时也增加了它的size!
原因如下:
reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。
resize是改变容器的大小,且在创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。此时再调用push_back()函数,是加在这个新的空间后面的。
两个函数的参数形式也有区别的,reserve函数之后一个参数,即需要预留的容器的空间;resize函数可以有两个参数,第一个参数是容器新的大小, 第二个参数是要加入容器中的新元素,如果这个参数被省略,那么就调用元素对象的默认构造函数。