vector的模拟实现

177 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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;
		}

首尾的标志beginend,首尾元素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;
    }
}