vector的模擬實現
阿新 • • 發佈:2019-01-13
vector和陣列看起來的卻別在於一個是靜態的,另外一個是動態的。而vector擴容時候,現要資料搬移到新的空間然後在釋放掉以前的空間。
我們模擬實現我們感覺最需要注意的還是擴容問題什麼時候擴容什麼時候不用擴容。
已經一個檢查vector擴容的介面函式
也不知怎麼說vector常用的介面,感覺主要分三類,第一類建立vector類,第二類修改vector元素類,第三類遍歷元素類。
-感覺vector涉及到元素修改時候我們都需要注意的一個因素就是迭代器失效了,以及在細分三種情況
- 第一種修改以後空間給reserve申請的空間更大,不能裝滿觸發了擴容,我們需要經行擴容然後搬移資料,在銷燬以前的空間。
- 第二種我們雖然修改了元素,但是我們申請的元素空間沒有用完,但是比上一次修改元素操作所佔用的元素空間大,我們只需要在原有空間上插入資料。並不需要經行元素的搬移。
- 第三種我們這次操作比以前的操作資料的大小還要小的情況下,我們只需要改變元素的大小就可以了。第三種雖然簡單一些,但是我感覺還是最容易忘記的,有時候減少元素我們會忘記考慮判空,在resize當中也有這種情景,但是我們卻很容易葫蘆這一種情況。
好了,看程式碼吧
#include<iostream> #include<vector> #include<assert.h> using namespace std; template<class T> class Vector { public: typedef T* Iterator; public: Vector() : _start(0) , _finish(0) , _endOfStorage(0) {} Vector(size_t size, const T& data = T()) : _start(new T[size]) , _finish(_start + size) , _endOfStorage(_start + size) { for (size_t i = 0; i < size; ++i) _start[i] = data; } Vector(const T* first, const T* last) { size_t size = last - first; _start = new T[size]; // 1. for (size_t i = 0; i < size; ++i) _start[i] = first[i]; _finish = _start + size; _endOfStorage = _finish; } Vector(const Vector<T>& v); Vector<T>& operator=(const Vector<T>& v); ~Vector() { if (_start) { delete[] _start; _start = 0; _finish = 0; _endOfStorage = 0; } } Iterator Begin() { return _start; } Iterator End() { return _finish; } void PushBack(const T& data) { _CheckCapacity(); *_finish = data; ++_finish; } void PopBack() { if (_start == _finish) return; --_finish; } void Clear() { _finish = _start; } void Swap(Vector<T>& v) { swap(_start, v._start); swap(_finish, v._finish); swap(_endOfStorage, v._endOfStorage); } size_t Size()const { return _finish - _start; } size_t Capacity()const { return _endOfStorage - _start; } bool Empty()const { return _start == _finish; } void ReSize(size_t newSize, const T& data = T()) { size_t oldSize = Size(); if (newSize <= oldSize) _finish = _start + newSize; else { size_t capacity = Capacity(); if (newSize < capacity) { while (newSize != oldSize) { *_finish = data; ++_finish; --newSize; } } else { T* pTmp = new T[newSize]; if (_start) { for (size_t i = 0; i < oldSize; ++i) pTmp[i] = _start[i]; for (size_t i = oldSize; i < newSize; ++i) pTmp[i] = data; delete[] _start; } _start = pTmp; _finish = _start + newSize; _endOfStorage = _finish; } } } void Reserve(size_t n) { if (n > Capacity()) { size_t size = Size(); T* pTmp = new T[n]; if (_start) { for (size_t i = 0; i < size; ++i) pTmp[i] = _start[i]; delete[] _start; } _start = pTmp; _finish = _start + size; _endOfStorage = _start + n; } } T& operator[](size_t index) { assert(index < Size()); return _start[index]; } const T& operator[](size_t)const { assert(index < Size()); return _start[index]; } T& Front() { return *_start; } const T& Front()const { return *_start; } T& Back() { return *(_finish - 1); } const T& Back()const { return *(_finish - 1); } private: void _CheckCapacity() { if (_finish == _endOfStorage) { size_t size = Size(); size_t newSize = size * 2 + 3; T* pTmp = new T[newSize]; if (_start) { // 如何區分T是否為內建型別? if (false) { memcpy(pTmp, _start, size * sizeof(T)); } else { for (size_t i = 0; i < size; ++i) pTmp[i] = _start[i]; } delete[] _start; } _start = pTmp; _finish = _start + size; _endOfStorage = _start + newSize; } } private: T* _start; T* _finish; T* _endOfStorage; }; void TestVectorint() { Vector<int> v1; v1.PushBack(1); v1.PushBack(2); v1.PushBack(3); v1.PushBack(4); cout << v1.Size() << endl; cout << v1.Capacity() << endl; cout << v1.Front() << endl; cout << v1.Back() << endl; for (size_t i = 0; i < v1.Size(); ++i) cout << v1[i] << " "; cout << endl; v1.PopBack(); v1.PopBack(); cout << v1.Size() << endl; cout << v1.Capacity() << endl; cout << v1.Front() << endl; cout << v1.Back() << endl; for (size_t i = 0; i < v1.Size(); ++i) cout << v1[i] << " "; cout << endl; v1.ReSize(20, 9); Vector<int>::Iterator it = v1.Begin(); while (it != v1.End()) { cout << *it << " "; ++it; } cout << endl; } int main() { TestVectorint(); return 0; }
我們通過模擬的迭代器遍歷一遍。
好了,具體就這樣樣了,主要是介面比較多一點,但是基本思路也就上面這一點的。