vector是我们C++中会经常使用的一个容器类型,可以将其理解成一个可变换大小的数组。因此,vector也是采用连续存储空间对数据进行存储,可以使用下标对其进行访问,但是与数组有区别的在于,其大小可以动态改变的。其详细操作请参考vector使用手册。
我们在本文中主要探讨一些常用功能的底层模拟实现,从而更加深刻的理解其原理。
目录
_Vector模板框架
template<class T>
class _Vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
private:
//空间的首地址
iterator _start;
//指向最后一个有效元素的结尾
iterator _finish;
//空间的结尾
iterator _endof;
};
不同的构造函数_Vector()
//无参构造函数
_Vector()
:_start(nullptr),
_finish(nullptr),
_endof(nullptr)
{}
//指定个数参数的构造
_Vector(size_t n, const T& val = T())
:_start(new T[n])
, _finish(_start + n)
, _endof(_start + n)
{
for (size_t j = 0; j < n; ++j)
{
_start[j] = val;
}
}
//通过迭代器构造
template<class input_iterator>
_Vector(input_iterator first, input_iterator end)
:_start(nullptr),//不知道空间大小初始为空
_finish(nullptr),
_endof(nullptr)
{
while (first != end)
{
pushback(*first);//进行尾插赋值
first++;
}
}
尾插以及任意位置插入元素pushback()、_insert()
//尾插
void pushback(const T& val)
{
//第一步检查容量
is_capacity();
//第二步插入元素
*_finish = val;
//第三步更新数据
_finish++;
}
//某个位置进行插入,通过迭代器
void _insert(iterator pos, const T& val = T())
{
//检查位置是否符合
assert(pos <= _finish&&pos >= _start);
//考虑迭代器失效问题
size_t offnum = pos - _start;
//检查容量
is_capacity();
pos = _start + offnum;
//移动元素
iterator _end = _finish;
while (_end != pos)
{
*_end-- = *(_end - 1);
}
*pos = val;
++_finish;
}
尾删及删除某一位置元素_erase()、_popback()
//删除某一位置元素
iterator _erase(iterator pos)
{
//检查位置是否合法
assert(pos < _finish && pos >= _start);
//移动元素
iterator ppos = pos;
while (ppos != _finish)
{
*(ppos - 1)= *ppos;
ppos++;
}
//更新位置
_finish--;
return ppos;
}
//尾删
void _popback()
{
if (_size() > 0)
_erase(end() - 1);
}
检查容量接口is_capacity()
//检查容量接口
void is_capacity()
{
if (_finish == _endof)
{
size_t new_capa = _endof == nullptr ? 1 : 2 * _capacity();
_reserve(new_capa);//增加容量
}
}
增加容量接口_reserve()
//增加容量
void _reserve(size_t n)
{
if (n > _capacity())
{//保存有效元素个数
size_t num = _size();
//申请空间
T* temp = new T[n];
//拷贝原始内容,拷贝有效的元素
if (_start)
{
memcpy(temp, _start, sizeof(T)*_size());
//释放原有空间
delete[] _start;
}
//更新起始位置以及其他参数
_start = temp;
_endof =_start + n;
// _finish = _start + _size();//不能直接调用_size()接口
_finish = _start + num;
}
}
改变有效元素个数 _resize()
//改变有效元素个数
void _resize(size_t n,const T& val=T())
{
//n>容量,先开辟空间
if (n > _capacity())
{
_reserve(n);
}
//进行赋值
if (n > _size())
{
while (_finish != _start + n)
*_finish++ = val;
}
//n<_size(),更新数据
_finish = _start + n;
}
有效元素个数_size()
//有效元素的个数
size_t _size()const
{
return _finish - _start;
}
实际容量大小_capacity()
//实际空间大小
size_t _capacity()const
{
return _endof - _start;
}
迭代器iterator
//迭代器
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator begin() const
{
return _start;
}
const_iterator end()const
{
return _finish;
}
[]重载
//[]方式遍历
T& operator[](size_t p)
{
assert(p < _size());
return _start[p];
}
const T& operator[](size_t p)const
{
assert(p < _size());
return _start[p];
}
三种遍历方式 迭代器、for、[]
//使用迭代器输出
template<class T>
void printVector(_Vector<T>& v,const T& val)
{
_Vector<T>::iterator p = v.begin();
while (p != v.end())
{
cout << *p << ' ';
*p = val;
++p;
}
cout << endl;
}
template<class T>
void printVector(const _Vector<T>& v)
{
_Vector<T>::const_iterator p = v.begin();
while (p != v.end())
{
cout << *p << ' ';
++p;
}
cout << endl;
}
//使用for输出
template<class T>
void printVector_for(_Vector<T>& v, const T& val)
{
for (auto& p : v)
{
cout << p << ' ';
p = val;
}
cout << endl;
}
template<class T>
void printVector_for(const _Vector<T>& v)
{
for (const auto& p : v)
{
cout << p << ' ';
}
cout << endl;
}
//使用[]输出
template<class T>
void printvector_k(_Vector<T>& v, const T& val)
{
for (size_t i = 0; i < v._size(); ++i)
{
cout << v.operator[](i) << ' ';
v[i] = val;
}
cout << endl;
}
template<class T>
void printvector_k(const _Vector<T>& v)
{
for (size_t i = 0; i < v._size(); ++i)
{
cout << v.operator[](i) << ' ';
}
cout << endl;
}