实现vector容器

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:18px;">背景:</span></span>

在c++ STL中 每一种容器都有其自己对应的迭代器实现。迭代器也成为了算法和容器之间的桥梁。今天先模拟一下vector 容器,以及对应的迭代器。

想法:

一、vector实质是可变长的数组(空间连续),所谓的可变长其实是伪可变长。为了实现可变长,vector的工作实质:
1、初始分配空间大小时,分配按实际需求分配。
2、加入分配空间已经使用满了,再执行一次push_back会发生什么情况?其实是重新申请一个更大的空间(大约原有空间的1.5倍---vs2013),将原来空间的内容拷贝到现有的空间,然后再把需要压入的数追加到后面,最后,释放掉原有的空间。
根据第二条,我们就会发现,其实vector的可变长不是在原来空间上增加空间,而是寻求了更大的一块空间。所以叫伪可变长。
二、vector 的迭代器实质其实是指针,通过观察vector的迭代器实现的功能。operator++,operator==,operator!=,
operator *等,就会发现,其实,普通指针就天生具备,vector支持随机存取,普通指针也有这功能,所以,vector提供的就是Random Access iterators。

程序实现:

<span style="font-size:14px;">#include<iostream>

using namespace std;

template<class T>
class MyVec
{
	public:
	typedef  T*         Iterator  ;
	typedef  size_t    size_type;
	
	/* 构造函数 */
	public:
		MyVec():start(0),finish(0),end_of_storage(0){};
		
		MyVec(Iterator  p,int n);
		
		MyVec(int num,int value);
	
		~MyVec(){};
	/* 成员函数 */	
	public:	
		
		Iterator   begin(){return start;}
		
		Iterator   end(){return finish;}
		
		size_type size() const {return (finish - start);}
		
		size_type capacity() const {return (end_of_storage - start);}
		
		bool empty() {return start==finish;}
		
		T& operator[](int n) {return n>=0?*(start+n):*(finish+n);}
		
		void push_back(const  T&x);
		
		void clear();
		
		Iterator erase(Iterator ite) {
			if(++ite!=finish)
				memmove(ite,ite+1,(finish-ite-1)*sizeof T);
			--finish;
			return ite;
		} 
		
		
	private:
		Iterator   start; //使用空间头
		Iterator   finish;//使用空间尾
		Iterator   end_of_storage;//可用空间尾
};

template<class T>
MyVec<T>::MyVec(Iterator p,int n)
{
	start=new T[n];
	for(int i=0;i<n;i++)
		*(start+i)=*(p++);
	finish=start+n;
	end_of_storage=start+n;
}

template<class T>
MyVec<T>::MyVec(int num,int value)
{
	start=new T[num]();
	finish=start+num;
	end_of_storage=start+num;
}

template<class T>
void MyVec<T>:: push_back(const  T&x)
{
		if (finish!= end_of_storage)
		{
			*finish=x;
			++finish;
		}
		else
		{
			const size_type old_size = size();
			const size_type len = old_size!=0?2*old_size:1;
			Iterator newstart=new T[len];
			Iterator newfinish=newstart;
			memmove(newstart,start,(sizeof T)*size() );
			delete [] start;
			start=newstart;
			*(start+old_size)=x;
			finish=start+old_size+1;
			end_of_storage=start+len;
		}
}

template<class T>
void MyVec<T>:: clear() //clear 以后可用容量 不会发生变化,但是使用容量变为 0  暂且不改变值 只是将start 指向的值改为0 
{
	if (size()==0)
		return;
	finish=start;
	*start=0;
}

int main()
{
	/* 构造函数和容器预留空间的大小 */
	int data[10]={0,1,2,3,4,6,7,8,9};
	MyVec<int> vec; //验证默认的构造函数
	MyVec<int > vec1(20,8); //验证初始化一样值的构造函数
	MyVec<int > vec2(data,10);// 验证用数组初始化的构造函数
	cout<<"vec.capacity= "<<vec.capacity()<<endl;
	cout<<"vec.capacity= "<<vec1.capacity()<<endl;
	cout<<"vec.capacity= "<<vec2.capacity()<<endl;
	vec1.push_back(1);
	cout<<"vec1 after relocate capacity = "<<vec1.capacity(); //原有容量的两倍
	
	/* 遍历 */
	MyVec<int>::Iterator it=vec1.begin();
	for(;it!=vec1.end();it++)
		cout<<*it<<" ";
	cout<<endl;
	
	/* 擦除某元素和检验operator[] */
	vec1.erase(it-3);
	for(int i=0;i<vec1.size();i++)
		cout<<vec1[i]<<" ";
	cout<<endl;
	/* 其他的成员函数 */
	cout<<vec1.empty()<<endl;
	vec1.clear();
	cout<<vec1.size()<<endl;
	

}</span>

下一节分析一下使用vector和重写vector中的一些问题。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值