持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
vector就是一个顺序表而已,只不过它是类模板,可以实例化出不同的模板类。下面我们通过模拟实现来进一步的熟悉vector。
vector的成员变量
与顺序表的成员不一样,顺序表的成员变量是指向数组的一个指针,实际数据的大小,空间的容量。而
vector的成员变量都是指针,三个指针,分别为指向所开空间的头,指向实际数据的尾,指向空间的尾。那么size,capacity也都可以很容易的表示出来。
template<class T>
class vector
{
public:
typedef T* iterator;
private:
iterator start;
iterator finish;//这里的finish指向的是最后一个数的下一个位置
iterator end_of_storage;
};
计算它的大小size,容量capaticy
size=finish-start,capacity=end_of_storage-start
size_t size()
{
return finish - start;
}
size_t capacity()
{
return end_of_storage - start;
}
首尾的标志begin,end,首尾元素front,back
begin就直接返回第一个元素的地址,end返回最后一个元素的地址。
iterator begin()
{
return start;
}
iterator end()
{
return finish;
}
front,back
T& front()
{
return *start;
}
T& back()
{
return *(finish - 1);
}
[]运算符的重载
首先要判断一下位置是否合法。同时还要返回引用,因为可能会对数据进行修改。
T& operator[](size_t pos)
{
assert(pos < size());
return *(start + pos);
}
const T& operator[](size_t pos)const
{
assert(pos < size());
return *(start + pos);
}
判断是否为空empty
只需要判断头尾是否相等就可以,相等就是空,不相等就不为空。
bool empty()
{
return start == finish;
}
构造,析构函数
构造函数
无参的拷贝构造,对应无参的构造函数直接都初始化为空指针就可以。
vector()
:start(nullptr)
, finish(nullptr)
, end_of_storage(nullptr)
{}
析构函数
对申请的空间进行释放
~vector()
{
delete[] start;
start = finish = end_of_storage = nullptr;
}
改变容量的大小reserve
对于
reserve,当给的参数小于等于实际空间大小的时候,此操作是不容许的,所以不会有什么操作,只有当大于实际空间的时候才会进行扩容。
void reserve(size_t n)
{
if (n > capacity())
{
size_t sz = size();
T* tmp = new T[n];
if (start)
{
for (size_t i = 0; i < sz; ++i)
{
tmp[i] = start[i];
}
delete[] start;
}
start = tmp;
finish = start + sz;
end_of_storage = start + n;
}
}