精通C++ STL(四):vector的模拟实现

目录

vector各函数接口总览

vector当中的成员变量介绍

默认成员函数 

        构造函数1

        构造函数2

        构造函数3

        拷贝构造函数

        赋值运算符重载函数

        析构函数

迭代器相关函数

        begin和end

容量和大小相关函数

        size和capacity

        reserve

        resize

        empty

修改容器内容相关函数

        push_back

        pop_back

        insert

        erase

        swap

访问容器相关函数

        operator[ ]


 

vector各函数接口总览

namespace Russ_Leo
{
	//模拟实现vector
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;

		//默认成员函数
		vector();                                           //构造函数
		vector(size_t n, const T& val);                     //构造函数
		template<class InputIterator>                      
		vector(InputIterator first, InputIterator last);    //构造函数
		vector(const vector<T>& v);                         //拷贝构造函数
		vector<T>& operator=(const vector<T>& v);           //赋值运算符重载函数
		~vector();                                          //析构函数

		//迭代器相关函数
		iterator begin();
		iterator end();
		const_iterator begin()const;
		const_iterator end()const;

		//容量和大小相关函数
		size_t size()const;
		size_t capacity()const;
		void reserve(size_t n);
		void resize(size_t n, const T& val = T());
		bool empty()const;

		//修改容器内容相关函数
		void push_back(const T& x);
		void pop_back();
		void insert(iterator pos, const T& x);
		iterator erase(iterator pos);
		void swap(vector<T>& v);

		//访问容器相关函数
		T& operator[](size_t i);
		const T& operator[](size_t i)const;

	private:
		iterator _start;        //指向容器的头
		iterator _finish;       //指向有效数据的尾
		iterator _endofstorage; //指向容器的尾
	};
}

vector当中的成员变量介绍

        在 vector 中有三个成员变量:_start_finish_endofstorage

        _start指向容器的头,_finish指向容器当中有效数据的尾,_endofstorage指向整个容器的尾。 

默认成员函数 

        构造函数1

        vector 首先支持一个无参的构造函数。对于这个构造函数,我们可以直接将对象的三个成员变量都初始化为 空指针

//构造函数1
vector()
	:_start(nullptr)
	, _finish(nullptr)
	, _endofstorage(nullptr)
{}

        构造函数2

        此外,vector 还支持使用一段迭代器区间来构造对象。由于这个迭代器区间可以是其他容器的迭代器区间,也就是说,该函数接收到的迭代器类型是不确定的,因此我们需要将该构造函数设计为一个函数模板。在函数体内,我们只需将该迭代器区间的数据逐个尾插到容器中即可。

//构造函数2
template<class InputIterator> //模板函数
vector(InputIterator first, InputIterator last)
	:_start(nullptr)
	, _finish(nullptr)
	, _endofstorage(nullptr)
{
	//将迭代器区间在[first,last)的数据一个个尾插到容器当中
	while (first != last)
	{
		push_back(*first);
		first++;
	}
}

        构造函数3

        另外,vector 还支持构造包含n个值为val的容器。对于这个构造函数,我们可以先使用 reserve 函数将容器的容量设置为 n,然后使用 push_back 函数尾插 n 个值为 val 的数据到容器中。

//构造函数3
vector(size_t n, const T& val)
	:_start(nullptr)
	, _finish(nullptr)
	, _endofstorage(nullptr)
{
	reserve(n); //调用reserve函数将容器容量设置为n
	for (size_t i = 0; i < n; i++) //尾插n个值为val的数据到容器当中
	{
		push_back(val);
	}
}

注意:

  1. 该构造函数知道需要存储 n 个数据的空间,因此最好使用 reserve 函数一次性开辟足够的空间,避免在调用 push_back 函数时多次增容,从而降低效率。
  2. 该构造函数还需要实现两个重载函数
vector(long n, const T& val)
	:_start(nullptr)
	, _finish(nullptr)
	, _endofstorage(nullptr)
{
	reserve(n); //调用reserve函数将容器容量设置为n
	for (size_t i = 0; i < n; i++) //尾插n个值为val的数据到容器当中
	{
		push_back(val);
	}
}
vector(int n, const T& val)
	:_start(nullptr)
	, _finish(nullptr)
	, _endofstorage(nullptr)
{
	reserve(n); //调用reserve函数将容器容量设置为n
	for (int i = 0; i < n; i++) //尾插n个值为val的数据到容器当中
	{
		push_back(val);
	}
}

        可以看到,这两个重载函数的区别在于参数 n 的类型不同,但这是必要的。否则,当我们使用以下代码时,编译器会优先匹配构造函数2。 

vector<int> v(5, 7); //调用构造函数3 ???

        并且,由于构造函数2中对参数 firstlast 进行了解引用操作,而 int 类型无法进行解引用操作,这会导致报错。 

        拷贝构造函数

        vector 的构造函数涉及深拷贝问题,这里提供两种深拷贝的写法:

写法一:传统写法

        传统的拷贝构造方法思想最为直观:首先开辟一块与该容器大小相同的空间,然后将容器中的数据逐个拷贝过来,最后更新 _finish_endofstorage 的值。

//传统写法
vector(const vector<T>& v)
	:_start(nullptr)
	, _finish(nu
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值