文章目錄
- 介紹
- initializer_list
- 與string的不同
- 底層
- 總代碼
介紹
C++ 中的 vector 是一種序列容器,它允許你在運行時動態地插入和刪除元素。
vector 是基于數組的數據結構,但它可以自動管理內存,這意味著你不需要手動分配和釋放內存。
與 C++ 數組相比,vector 具有更多的靈活性和功能,使其成為 C++ 中常用的數據結構之一。
vector 是 C++ 標準模板庫(STL)的一部分,提供了靈活的接口和高效的操作。
C++ 中的 vector 是一種序列容器,它允許你在運行時動態地插入和刪除元素
vector本質和 string一樣也是模板
寫法是vector< T > 名稱 (T是類型)
他與string的接口差不多,但也有一點不同 。
我們來 看一下vector的構造,第一個是默認構造(看不懂的是內存池先不用管),第二個是n個 val的構造,第三個是迭代器區間的構造,第四個是拷貝構造。
initializer_list
vector 中和string比較增加了 initializer_list容器,這個容器可以作為接口的形參出現。
本身我們的{ }里面的內容就是initializer_list類型的
如
這3段代碼 不同,d1本身是是vector< int >型的接受的類型類似于d3 是initializer_list< int >型但是它進行了隱式類型轉化。
d2就是{1,2,3,4}作為形參傳過去,d3則是{ }的真正類型。
與string的不同
此外vector和string類不同就是vector沒有append函數就是不能加一個字符串,即使是vector< string >也只能一個一個加。
從兩邊形參上看vector只支持迭代器位置的修改,而string還支持下標位置pos的修改,同理其他接口 如erase也是這樣
底層
首先我們要知道 和string不一樣,定義char ,capacity,size。vector的成員變量都是 用迭代器定義的,我們 又可以把迭代器看作是T 就是類似于指針的東西,所以vector 就是 用指針定義的成員變量。
namespace Z
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;
privite:iterator _start;//頭指針類似于.begin()iterator _finish;//結尾元素的下一位置,類似于.end()iterator _endofstorage;//類似capacity,_start-_finish得來};
我們再來寫構造函數有默認構造,還有無參構造還有initializer_list構造,析構,還有拷貝構造
vector()//默認:_start(nullptr),_finish(nullptr),_endofstorage(nullptr){}vector(initializer_list<T> il)//initializer_list構造:_start(nullptr), _finish(nullptr), _endofstorage(nullptr){reserve(il.size());for (auto& e : il){push_back(e);}}~vector()//析構{if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}
vector(initializer_list<T> il)//initializer_list類型:_start(nullptr), _finish(nullptr), _endofstorage(nullptr)
{reserve(il.size());for (auto& e : il){push_back(e);}
}
其中initializer_list類型的reserve和 push_back都是省略this指針的。
常見 的一些接口
iterator begin()
{return _start;
}iterator end()
{return _finish;
}const_iterator begin() const
{return _start;
}const_iterator end() const
{return _finish;
}
T& operator[](size_t i)
{assert(i < size());return _start[i];
}size_t size() const
{return _finish - _start;
}size_t capacity() const
{return _endofstorage - _start;
}// 21:12
void reserve(size_t n)
{if (n > capacity()){size_t oldSize = size();T* tmp = new T[n];if (_start){memcpy(tmp, _start, sizeof(T) * oldSize);delete[] _start;}_start = tmp;_finish = _start + oldSize;_endofstorage = _start + n;}
}void push_back(const T& x)
{/*if (_finish == _endofstorage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finish = x;++_finish;*/insert(_finish, x);
}bool empty()
{return _start == _finish;
}void pop_back()
{assert(!empty());--_finish;
}void insert(iterator pos, const T& x)
{assert(pos >= _start && pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _start + len;}iterator i = _finish - 1;while (i >= pos){*(i + 1) = *i;--i;}*pos = x;++_finish;
}
總代碼
namespace Z
{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():_start(nullptr), _finish(nullptr), _endofstorage(nullptr){}vector(initializer_list<T> il):_start(nullptr), _finish(nullptr), _endofstorage(nullptr){reserve(il.size());for (auto& e : il){push_back(e);}}~vector(){if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}T& operator[](size_t i){assert(i < size());return _start[i];}size_t size() const{return _finish - _start;}size_t capacity() const{return _endofstorage - _start;}// 21:12void reserve(size_t n){if (n > capacity()){size_t oldSize = size();T* tmp = new T[n];if (_start){memcpy(tmp, _start, sizeof(T) * oldSize);delete[] _start;}_start = tmp;_finish = _start + oldSize;_endofstorage = _start + n;}}void push_back(const T& x){/*if (_finish == _endofstorage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finish = x;++_finish;*/insert(_finish, x);}bool empty(){return _start == _finish;}void pop_back(){assert(!empty());--_finish;}void insert(iterator pos, const T& x){assert(pos >= _start && pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _start + len;}iterator i = _finish - 1;while (i >= pos){*(i + 1) = *i;--i;}*pos = x;++_finish;}void erase(iterator pos);private:iterator _start;iterator _finish;iterator _endofstorage;};