vector的实现
基础框架
class vector
{
public:
// 重命名几种类型
typedef T value_type;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef value_type& reference;
typedef const value_type& const_reference;
private:
// 几个迭代器
iterator _start;
iterator _finish;
iterator _end_of_storage;
public:
iterator begin() { return _start; }
iterator end() { return _finish; }
const_iterator begin() const { return _start; }
const_iterator end() const { return _finish; }
size_t size() const { return _finish - _start; }
size_t capacity() const { return _end_of_storage - _start; }
void reserve(size_t n)
{
if (n > capacity())
{
value_type* tmp = new value_type[n];
size_t old_size = size(); // 这里需要有一个old_size,防止后面更新_start后_finish为0
if (_start)
{
// memcpy(tmp, _start, sizeof(value_type) * old_size);
for (size_t i = 0; i < old_size; ++i)
{
tmp[i] = _start[i];
}
}
delete[] _start;
// 调整迭代器
_start = tmp;
_finish = _start + old_size;
_end_of_storage = _start + n;
}
}
reference operator[](size_t n) { return *(begin() + n); }
const_reference operator[](size_t n) const { return *(begin() + n); }
void push_back(const T& x)
{
// 空间满了要扩容
if (_finish == _end_of_storage)
capacity() == 0 ? reserve(4) : reserve(2 * capacity());
*_finish = x; // 注意这里有个 * 解引用
++_finish;
}
void pop_back()
{
assert(_start < _finish);
--_finish;
}
vector()
: _start(nullptr)
, _finish(nullptr)
, _end_of_storage(nullptr)
{}
~vector()
{
delete[] _start;
_start = _finish = _end_of_storage = nullptr;
}
};
insert和erase
void insert(iterator pos, const value_type& x)
{
assert(pos >= _start);
assert(pos <= _finish);
// 空间满了要扩容
if (_finish == _end_of_storage)
{
// 保存一下pos的位置,防止扩容后pos变成野指针导致迭代器失效
size_t len = pos - _start;
capacity() == 0 ? reserve(4) : reserve(2 * capacity());
pos = _start + len;
}
// 挪动数据
iterator end = _finish;
while (end != pos)
{
*end = *(end - 1);
--end;
}
*pos = x;
++_finish;
}
iterator erase(iterator pos)
{
assert(pos >= _start);
assert(pos < _finish); // 这里没有等于
iterator cur = pos;
while (cur != _finish)
{
*cur = *(cur + 1);
++cur;
}
--_finish;
return pos; // 返回删除位置下一个的迭代器
}
测试insert迭代器失效
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
auto p = find(v.begin(), v.end(),3);
if (p != v.end())
{
v.insert(p, 30); // 如果insert不处理就会导致迭代器失效
// 使用insert之后,不要再继续访问
// v.insert(p, 400);
}
erase的问题
// 测试erase,假设想要删除vector中所有的偶数
void test_erase()
{
v.push_back(1);
v.push_back(2);
v.push_back(4);
v.push_back(3);
v.push_back(4);
v.push_back(5);
vector<int>::iterator it = v.begin();
while (it != v.end())
{
if ((*it) % 2 == 0)
{
v.erase(it);
}
++it;
}
}
上面的代码结果不对(1 4 3 5),当输入数据为1 2 3 4的时候甚至会崩溃,原因在下面
所以,stl的erase提供一个返回值,返回删除位置的下一个元素的迭代器,因此,下面的代码才是对的
while (it != v.end())
{
if ((*it) % 2 == 0)
it = v.erase(it);
else
++it;
}
总结:insert,erase pos位置后,不要再次访问pos,可能会出现各种出乎意料的结果,这就是迭代器失效
迭代器失效解决办法:在使用前,对迭代器重新赋值即可
拷贝构造函数
// 传统的拷贝构造函数
// v(v1)
vector(const vector<value_type>& v1)
{
_start = new value_type[v1.size()]; // v1的capacity()也可以
//memcpy(_start, v1._start, v1.size() * sizeof(value_type));
// 需要这样写,要不然vector是二维数组的时候会报错
for (size_t i = 0; i < v1.size(); ++i)
{
_start[i] = v1[i]; // T对象是自定义类型时,调用T对象的opeartor=
}
_finish = _start + v1.size();
_end_of_storage = _start + v1.size();
}
// 另一种写法
// v(v1)
vector(const vector<value_type> &v1)
:_start(nullptr)
,_finish(nullptr)
,_end_of_storage(nullptr)
{
reserve(v1.size());
for (const auto& e : v1) // 这里最好要有引用
push_back(e);
}
// 若想实现现代写法, 需要再写一个有参构造函数
// 带迭代器区间的构造函数
// 模板的作用是让传进来的迭代器可以是任意容器的迭代器
template<typename InputIterator>
vector(InputIterator first, InputIterator last)
:_start(nullptr)
,_finish(nullptr)
,_end_of_storage(nullptr)
{
while (first != last)
{
push_back(*first);
++first;
}
}
// 现代写法
void swap(vector<value_type>& v)
{
::swap(_start, v._start);
::swap(_finish, v._finish);
::swap(_end_of_storage, v._end_of_storage);
}
vector(const vector<value_type> &v1)
:_start(nullptr)
,_finish(nullptr)
,_end_of_storage(nullptr)
{
vector<value_type> tmp(v1.begin(), v1.end());
swap(tmp);
}
赋值构造函数
// 赋值构造函数-传统写法
// v = v1
vector<value_type>& operator=(vector<value_type> v1)
{
if (this != &v1)
{
// 删除旧的空间
delete[] _start;
// 开新空间
_start = new value_type[v1.size()];
// 拷贝数据
memcpy(_start, v1._start, sizeof(value_type) * v1.size());
_finish = _start + v1.size();
_end_of_storage = _start + v1.capacity();
}
return *this;
}
// 赋值构造函数,现代写法
vector<value_type>& operator=(vector<value_type> v) // 需要先写完拷贝构造
{
swap(v);
return *this;
}
resize()
void resize(size_t n, value_type val = value_type())
{
// 扩容
if (n > capacity())
reserve(n);
// 如果大于size(),就初始化数据
if (n > size())
{
while (_finish != _start + n)
{
*_finish = val;
++_finish;
}
}
// n<size(), 删除数据
else
{
_finish = _start + n;
}
}