目錄
💕?1.vector三個核心
💕2.begin函數,end函數的實現(簡單略講)
💕3.size函數,capacity函數的實現 (簡單略講)
💕4.reserve函數實現?(細節詳見)
💕5.resize函數實現(簡單略講,純小計算)
💕6.其他功能函數實現(略講,都是順序表那一套沒有改變)?
💕7.整體代碼實現
💕8.底層模擬測試 .cpp
💕9.完結?
一個人的堅持到底有多難?
?
?聲明:此文內容基于此文章->:【C++】STL——vector的使用
💕?1.vector三個核心
在vector中,核心成員并不是我們在數據結構實現的順序表,如size,capacity,data,而是下面三個->:
#pragma once #include<iostream> #include<assert.h> using namespace std; namespace yz {template<class T>class vector{typedef T* iterator;typedef const T* const_iterator;public:private:iterator _start = nullptr;iterator _finish = nullptr;iterator _end_of_storage = nullptr;};}
我們把元素的地址T*,命名為迭代器類型,iterator
接下來分別是順序表起始位置的地址,順序表的 size 用 _finish 來表示,順序表的capacity用_end_of_storage來表示
💕2.begin函數,end函數的實現(簡單略講)
我們知道vector庫中的begin函數與end函數返回的雖然是迭代器,但是可以像指針一樣使用,因此我們可以很好的實現,如下->:
iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin()const{return _start;}const_iterator end()const{return _finish;}
💕3.size函數,capacity函數的實現 (簡單略講)
size函數與capacity函數的實現更是簡單,直接用指針相減即可
size_t size(){return _finish - _start;}size_t capacity(){return _end_of_storage - _start;}
💕4.reserve函數實現?(細節詳見)
代碼看不懂的請往下看圖片講解
//reserve預留空間T* reserve(size_t n){size_t old_size = size();if (n > capacity()){T* tep = new T[n+1];//開辟n個空間,+1是為了單獨考慮string//將內容復制過去for (int i = 0; i < size(); i++){tep[i] = _start[i];}delete[] _start;_start = tep;_finish = _start + old_size;_end_of_storage = _start + n;tep = nullptr;}return _start;}
我們知道,capacity函數開辟的新空間只會增大,不會縮小,而開辟新空間我們需要做的第一件事就是轉移數據
這里需要先思考下如何轉移,如果用strcpy只可以轉移string類,那怎么辦?用memmove嗎?
不,memmove的復制時一個字節一個字節復制過去的,雖然復制int,double時沒有問題,但如果復制的是stirng類型,我們知道,string類的成員變量是字符串首地址,在使用memmove復制時字符串的首地址原封不動的復制了過去,這就會造成我們在釋放舊空間后,白進行了memmove的復制,這是不可取的,所以我們要用到for循環轉移數據,下面有圖->:
轉移數據思考完了,我們接著思考為什么要old_size,我們拷貝完數據后,需要轉移的就是三大核心,start,finish,和end_of_storage,那么我們將數據轉移后,釋放掉原來的舊空間,就會導致finish和end_of_storage指向的是野指針,所以我們需要保留原來的old_size,這樣才能讓finish指向正確的位置
💕5.resize函數實現(簡單略講,純小計算)
//resize預留空間 T* resize(size_t n,const T& val) {if (n > size()){reserve(n);//先開辟出足夠的空間size_t newsize = n - size();while (newsize > 0){*(_finish++) = val;newsize--;}}return _start; }
💕6.其他功能函數實現(略講,都是順序表那一套沒有改變)?
//判斷空 bool empty() {if (size() == 0){return true;} } //尾插 void push_back(const T& x) {if (size() == capacity()) {size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reverse(newcapacity);}*_finish = x;_finish++; } //尾刪 void pop_back() {empty();*_finish = 0;_finish--; } //指定位置插入 void insert(iterator pos, const T& val) {assert(pos >= _start && pos <= _finish);if (size() == capacity()) {size_t count = pos - _start;size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reverse(newcapacity);pos = _start + count;}T* tep = _finish;while (tep >= pos){*(tep) = *(tep - 1);tep--;}*(pos) = val;_finish++; } void erase(iterator pos) {assert(pos >= _start && pos < _finish);empty();_finish--;while (pos < _finish){*(pos) = *(pos + 1);pos++;} }
💕7.整體代碼實現
#pragma once #include<iostream> #include<assert.h> using namespace std; namespace yz {template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin()const{return _start;}const_iterator end()const{return _finish;}size_t size(){return _finish - _start;}size_t capacity(){return _end_of_storage - _start;}//reserve預留空間T* reserve(size_t n){size_t old_size = size();if (n > capacity()){T* tep = new T[n+1];//開辟n個空間,+1是為了單獨考慮string//將內容復制過去for (int i = 0; i < size(); i++){tep[i] = _start[i];}delete[] _start;_start = tep;_finish = _start + old_size;_end_of_storage = _start + n;tep = nullptr;}return _start;}//resize預留空間T* resize(size_t n,const T& val){if (n > size()){reserve(n);//先開辟出足夠的空間size_t newsize = n - size();while (newsize > 0){*(_finish++) = val;newsize--;}}return _start;}//判斷空bool empty(){if (size() == 0){return true;}}//尾插void push_back(const T& x){if (size() == capacity()) {size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reverse(newcapacity);}*_finish = x;_finish++;}//尾刪void pop_back(){empty();*_finish = 0;_finish--;}//指定位置插入void insert(iterator pos, const T& val){assert(pos >= _start && pos <= _finish);if (size() == capacity()) {size_t count = pos - _start;size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reverse(newcapacity);pos = _start + count;}T* tep = _finish;while (tep >= pos){*(tep) = *(tep - 1);tep--;}*(pos) = val;_finish++;}void erase(iterator pos){assert(pos >= _start && pos < _finish);empty();_finish--;while (pos < _finish){*(pos) = *(pos + 1);pos++;}}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _end_of_storage = nullptr;};}
💕8.底層模擬測試 .cpp
#define _CRT_SECURE_NO_WARNINGS #include"vector.h" int main() {yz::vector<int> a1;/*a1.resize(200,3);cout<<a1.size()<<' '<<a1.capacity();a1.empty();*/a1.insert(a1.begin(), 99);a1.insert(a1.begin(), 88);a1.push_back(0);a1.push_back(20);a1.push_back(28);a1.pop_back();a1.erase(a1.begin());a1.erase(a1.end()-1);a1.resize(200, 5);a1.reserve(300);yz::vector<int> a2;if (a2.empty()){cout << "空" << endl;}for (auto e : a1){cout << e << ' ';}}