(七)vector深度剖析

容器vector的实现

  • vector是一种动态增长的数组,在数组用完的时候,它会自动扩充。没有任何一种东西在内存中可以原地扩充,在当前数组用完后,它会在内存的另一个地方,重新开辟一个当前数组容量二倍大小的数组,将当前的元素全部移过去

2.9版

  • vector中有三个指针,start指向vector的起始位置,finish指向vector的最后一个元素,end_of_storage指向容器的最后一个空槽位的下一个位置。
template <class T, class Alloc = alloc>
clsaa vector{
public:
	typedef T value_type;
	typedef value_type* iterator;//T*
	typedef value_type& reference;
	typedef size_t size_type;
protected:
	//vector的大小是12,有三个指针
	iterator start;
	iterator finish;
	iterator end_of_storage;
public:
	iterator begin() { return start; }
	iterator end() { return finish; }
	size_type size() const
	{ return size_type(end() - begin()); }
	//为什么不直接两个指针相减,而是通过调用两个函数做差?
	//通过函数调用,即使实际上不是两个指针,它的设计更加复杂,结果也是这两个函数相减
	size_type capacity() const
	{ return size_type(end_of_storage - begin()); }
	bool empty() const { return begin() == end(); }
	//所有的连续存储的空间,都会提供[]操作符
	reference operator[] (size_type n)
	{ return *(begin() + n); }
	reference front() { return *begin(); }
	reference back() { return *(end() - 1); }
vector的两倍增长
  • 每次的扩充,都有大量的元素的拷贝操作,而拷贝操作要调用拷贝构造函数,且要将原来的元素释放掉,要调用多次析构函数,开销非常大。
void push_back(const T& x){
	if(finish != end_of_storage){//尚有使用空间
		construct(finish, x);//全局函数
		++finish;//指向最后一个元素的下一个位置
	}
	else//已无使用空间
		insert_aux(end(), x);
}

template <class T, class Alloc>
void vector<T, Alloc>::insert_aux(iterator position, const T& x){
	if( finish != end_of_storage){//尚有备用空间
		//在使用空间起始处再建一个元素,并以vector最后一个元素为其初始值
		construct(finish, *(finish - 1));
		++finish;//指向最后一个元素的下一个位置
		T x_copy = x;
		copy_backward(position, finish - 2, finish - 1);
		*position = x_copy;
	}
	else {//已无备用空间
		const size_type old_size = size();//记录原来的大小
		const size_type len = old_size != 0 ? 2 * old_size : 1;//计算新的空间
		///如果原大小为0,则新的大小为1,否则为原大小的二倍
		//前半段用来放原元素,后半段用来放新的元素
		
		iterator new_start = data_allocator::allocate(len);//分配好足够空间
		iterator new_finish = new_start;
		//
		try{
			//将原vector的内容拷贝到新vector
			new_finish = uninitialized_copy(start, position, new_start);
			construct(new_finish, x);//为新元素设置初值x
			++new_finish;//new_finish指向最后一个元素的下一个位置
			//拷贝安插点后的原内容(因为它也可能被insert(p, x)调用)
			new_finish = uninitialized_copy(position, finish, new_finish);
		}
		catch(...){
			//"commit or rollback"semantics
			destory(new_start, new_finish);
			data_allocator::deallocate(new_start, len);
			throw;
		}
		//解析并释放原vector
		destory(begin(), end());
		deallocate();
		//调整迭代器,指向新的vector
		start = new_start;
		finish = new_finish;
		end_of_storage = new_start + len;
	}
}
vector 的iterator
  • vector的迭代器是指针,在调用萃取器时时返回它的偏特化指针版本
template<class T, class Alloc = alloc>
class vector{
public:
	typedef T value_type;
	typedef value_type* iterator;//T*
	...
};

//使用萃取器,详细见(六)萃取器
vector<int> vec;
vector<int>::iterator ite = vec.begin();

//使用方法
iterator_traits<ite>:: iterator_category;
iterator_traits<ite>:: difference_type;
iterator_traits<ite>:: value_type;

4.9版

  • vector的继承关系

在这里插入图片描述

  • sizeof(vector)是12,有三个指针
vector的迭代器

在这里插入图片描述

  • 迭代器实质上是将指针封装成了对象,对应的是萃取器中的泛化版本
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值