对于vector相信大家并不陌生,这里介绍一些重要的vector的接口和用法。
1. 构造函数
vector(); 无参构造
vector(size_type n, const value_type& val = value_type()); 构造并初始化n个val
vector (InputIterator first, InputIterator last); 利用迭代器进行构造。
2. 拷贝构造
vector (const vector& x);
3. 迭代器的使用
iterator begin(); 获取第一个数据位置的 iterator
iterator end(); 获取最后一个数据下一个位置的 iterator
reverse_iterator rbegin(); 获取最后一个数据位置的 reverse_iterator 反向迭代器
reverse_iterator rend(); 获取第一个数据前一个位置的 reverse_iterator 反向迭代器
const_iterator cbegin(); 获取第一个数据位置的 const_iterator
const_iterator cend(); 获取最后一个数据的下一个位置的 const_iterator
关于vector迭代器失效问题:插入操作时有可能导致迭代器失效,因为插入时有可能增容,增容后迭代器还代表原来的空间的位置,而原来的空间已经释放。删除时也会导致迭代器失效,删除操作erase返回的是删除元素的下一个位置,其实迭代器指向的空间还在,只是不是我们所期望的了,也就是逻辑上的迭代器失效。
4. 容量空间等接口
size_t size(); 返回有效数据个数
size_t capacity(); 返回容量空间的大小
void resize(size_type n, value_type val = value_type()); 修改有效数据个数,若n 大于有效数据个数则在末尾添加值 val。
void reserve (size_type n); 修改容量大小 vs下默认增长为原来的 1.5 倍。
5. 增删查改等操作
void push_back (const value_type& val); 尾插
void pop_back(); 尾删
iterator insert (iterator position, const value_type& val); 在 position 位置前插入数据 value。 插入时有可能增容,增容后position还指向原来的空间,而原来的空间已经释放了。迭代器失效。
iterator erase (iterator position); 删除position位置的数据 删除后,position指向下一个元素,迭代器失效。
operator[] (size_type n); 像数组一样访问。
vector 模拟实现
namespace smx
{
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
iterator begin()
{
return start;
}
iterator end()
{
return finish;
}
const_iterator cbegin() const
{
return start;
}
const_iterator cend() const
{
return finish;
}
size_t size() const
{
return finish - start;
}
size_t capacity() const
{
return endofstorage - start;
}
vector() :start(nullptr)
, finish(nullptr)
, endofstorage(nullptr)
{
}
vector(size_t n, const T& value = T()) :start(nullptr)
, finish(nullptr)
, endofstorage(nullptr)
{
reserve(n);
while (n--)
{
push_back(value);
}
}
/*template<class input_iterator>*/
vector(iterator first, iterator last)
{
reserve(last - first);
while (first != last)
{
push_back(*first);
first++;
}
}
vector(const vector<T>& v)
{
reserve(v.capacity());
iterator it = begin();
const_iterator cit = v.cbegin();
while (cit != v.cend())
{
*it++ = *cit++;
}
finish = start + v.size();
endofstorage = start + v.capacity();
}
vector<T>& operator=(const vector<T>& v)
{
if (this != &v)
{
iterator tmp = new T[v.capacity()];
const_iterator cit = v.cbegin();
for (size_t i = 0; i < v.size(); i++)
{
*(tmp + i) = *(cit + i);
}
delete[] start;
start = tmp;
finish = start + v.size();
endofstorage = start + v.capacity();
}
return *this;
}
~vector()
{
delete[] start;
start = nullptr;
finish = nullptr;
endofstorage = nullptr;
}
void reserve(size_t n)
{
if (n > capacity())
{
size_t _size = size();
iterator tmp = new T[n];
if (start)
{
for (size_t i = 0; i < _size; i++)
{
*(tmp + i) = *(start + i);
}
}
delete[] start;
start = tmp;
finish = start + _size;
endofstorage = start + n;
}
}
void resize(size_t n, const T& value = T())
{
if (n < size())
{
finish = start + n;
return;
}
if (n > capacity())
{
reserve(n);
}
iterator it = finish;
finish = start + n;
while (it != finish)
{
*it = value;
it++;
}
}
void push_back(const T& x)
{
insert(end(), x);
}
void pop_back()
{
iterator it = end();
it--;
erase(it);
}
iterator insert(iterator pos,const T& x)
{
assert(pos <= finish);
if (size() == capacity())
{
size_t _size = size();
size_t position = pos - start;
size_t newcapacity = capacity() == 0 ? 1 : capacity() * 2;
reserve(newcapacity);
pos = start + position;
}
iterator _end = finish - 1;
while (_end >= pos)
{
*(_end + 1) = *_end;
--_end;
}
*pos = x;
++finish;
return pos;
}
iterator erase(iterator pos)
{
iterator _begin = pos + 1;
while (_begin <= finish)
{
*(_begin - 1) = *_begin;
++_begin;
}
--finish;
return pos;
}
T& operator[](size_t pos)
{
return *(start + pos);
}
private:
iterator start;
iterator finish;
iterator endofstorage;
};
}