1.?insert()
這個就是在指定位置插入一個元素,首先計算要插入的這個位置和開頭之間的距離,接著判斷那個_finish?有沒有碰到_endofstorage 或者_endofstorage 是不是為0,如果滿足條件,那就進行擴容,然后接著重新計算距離,因為我們經過擴容了,所以可能插入的位置會不準,所以要重新計算,接著我們算一個end,這個end就是最后一個元素的位置,然后通過挪動的方式留出pos的空間,接著插入對應元素再++_finish 。
void insert(iterator pos, const T& x)
{assert(pos >= _start && pos <= _finish);size_t len = pos - _start;if (_finish == _endofstorage && _endofstorage != 0){reserve(capacity() * 2);}else{reserve(4);}pos = _start + len;iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}*pos = x;++_finish;}
2. reserve()
這個函數就是改變vector的capacity,同時并不像resize一樣會添加或者減少元素。
首先保存當前元素數量 sz,然后動態分配大小為 n 的新內存 tmp。若原內存_start 非空,則通過循環調用元素的賦值運算符將原數據逐個復制到新內存中(而非直接使用 memcpy,避免淺拷貝問題),隨后釋放原內存。最后更新_start 指向新內存,_finish 指向原元素末尾的下一個位置,_endofstorage 指向新容量的末尾。若 n 不大于當前容量,則不執行任何操作。
簡單來說就是新開一個擴容后數組然后把舊的賦值給他,接著直接把原來的vector的三個指針直接指向新的,從而完成替換實現reserve。
void reserve(size_t n)
{if (n > capacity()){size_t sz = size();T* tmp = new T[n];if (_start){//memcpy(tmp, _start, sizeof(T) * sz);for (int i = 0; i < sz; i++) {tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start + n;}
}
3.? resize()
這個函數就是改變vector的大小,如果比原來的size小,那就改變finish的位置。
如果比原來的size大,那就吧finish向后移動,并在每一個添加的位置賦值為val。
PS:這個val之所以要設計成const T& val=T(),是因為我們并不知道這個vector里面是什么類型的,在加上這個resize在stl庫里面支持只給一個n,所以我們在這里就這么設計。意思是表用它的默認構造,我們在這里不用擔心int這種內置類型,因為C++支持像int a=int(1)這種語法了。
void resize(size_t n, const T& val=T())
{if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*(_finish) = val;++_finish;}}
}
4. swap()
這個的話就是交換兩個vetcor里面的內容。
原理上來說的話就是通過swap兩個vector里面的三個指針來實現。
void swap(vector<T>& v)
{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);
}
5. capacity()
這個的話就是返回vector的capacity,因為_endofstorage和_start是指針而不是實際的大小,所以我們在這里要做減法。
size_t capacity() const
{return (_endofstorage - _start);
}
6. size()
這個的話就是返回vector的size,原因的話和上面一樣。
size_t size() const
{return (_finish - _start);
}
7. operator[]
這個的話是運算符重載的[],簡單來說就是可以通過下標的方式來對vector里面的內容進行訪問。
同時在這里提供了普通版本和const版本。
T& operator[](size_t pos)
{ assert(pos < size());return _start[pos];
}const T& operator[](size_t pos) const
{assert(pos < size());return _start[pos];
}
8. print()
這個就是打印,通過迭代器的方式來對vector里面的內容進行打印。
void print()
{for (auto e : *this){std::cout << e << ' ';}cout << endl;
}
?9. 總結
本文圍繞C++中的vector容器展開了全面解析,從基礎特性到具體接口操作進行了系統梳理。
首先,明確了vector的核心特性及空間結構,讓讀者對其底層存儲有了整體認知;接著,深入講解了vector類的關鍵成員與函數,包括私有成員的作用,以及構造函數(默認、拷貝、范圍構造)和析構函數在對象創建與銷毀時的機制;同時,詳細介紹了迭代器相關的begin、end接口,以及erase、pop_back、insert等元素增刪操作,reserve、resize、swap等空間與容器管理函數,還有capacity、size的獲取方式;此外,還涵蓋了重載的方括號運算符(用于便捷訪問元素)和print方法(用于元素輸出)。
通過這些內容,全面呈現了vector的使用邏輯與核心功能,幫助讀者從底層原理到實際操作,完整掌握vector容器的應用。
以下是vector的完整代碼:
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
namespace struggle
{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;}vector(size_t n, const T& val = T()){resize(n, val);}vector(int n, const T& val = T()){resize(n, val);}template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}vector(const vector<T>& v){_start = new T[v.capacity()];for (size_t i = 0; i < v.size(); i++){_start[i] = v._start[i];}_finish =_start+v.size();_endofstorage = _start + v.capacity();}void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}vector<T>& operator=(vector<T> v){swap(v);return *this;}vector():_start(nullptr), _finish(nullptr), _endofstorage(nullptr){}~vector(){delete[] _start;_start = _finish = _endofstorage = 0;}void reserve(size_t n){if (n > capacity()){size_t sz = size();T* tmp = new T[n];if (_start){//memcpy(tmp, _start, sizeof(T) * sz);for (int i = 0; i < sz; i++) {tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start + n;}}void push_back(const T& x){if (_finish == _endofstorage && _endofstorage != 0){reserve(capacity() * 2);}else{reserve(4);}*_finish = x;++_finish;}size_t capacity() const{return (_endofstorage - _start);}size_t size() const{return (_finish - _start);}T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}void resize(size_t n, const T& val=T()){if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*(_finish) = val;++_finish;}}}void erase(iterator pos){assert(pos >= _start && pos < _finish);iterator it = pos;while (it + 1 != _finish){*it = *(it + 1);++it;}--_finish;}void pop_back(){assert(_start != _finish);--_finish;}void insert(iterator pos, const T& x){assert(pos >= _start && pos <= _finish);size_t len = pos - _start;if (_finish == _endofstorage && _endofstorage != 0){reserve(capacity() * 2);}else{reserve(4);}pos = _start + len;iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}*pos = x;++_finish;}/*void print(const vector<int>& v){for(auto e:v){std::cout << e << ' ';}cout << endl;}*/void print(){for (auto e : *this){std::cout << e << ' ';}cout << endl;}private:iterator _start;iterator _finish;iterator _endofstorage;};
}