从零开始制造一个STL之 vector

1 篇文章 0 订阅
1 篇文章 0 订阅

      STL有现成的,为什么要重新制造呢?为了锻炼自己,看看自己对底层了解到什么程度。话说前头,我可没有去研究过STL的源码,本人实力有限,看那玩意儿太恶心。vector——数组,我最熟悉的容器,在我看来是最容易实现的,所以从它开始。

vec类的声明

template<class type>
class vec
{
public:
	vec();//默认构造函数
	vec(unsigned int size,const type& data);//初始化构造函数
	vec(const vec& copy);//拷贝构造函数
	virtual ~vec();//析构函数
public:
	unsigned int size();//返回vec的元素数量
	void push_back(const type& data);//从vec最后面插入一个新元素
	void pop_back();//将vec最后一个元素删除 并且释放掉它的内存空间

	type& operator[](unsigned int i);//重载[]  然后可以用下标操作vec
	
	
public:
	typedef type* iter;//迭代器
	iter begin()//返回指向首元素的迭代器
	{
		it=_begin;
		return it;
	}
	iter end()//返回指向末尾元素的迭代器
	{
		it=_begin+_size;
		return it;
	}
	iter operator++()//重载++符号 用于操作迭代器
	{
		it=it+1;
	}
private:
	type* _begin;//vec的首地址
	unsigned int _size;//数组元素个数
	iter it;//迭代器	
};
下面是各个接口的实现,顺便提一下为什么很多函数的形参用的是const修饰加变量引用。因为type可能是一个类,变量引用可以避免重新构造一个对象,浪费空间。
const修饰是为了避免常量作为函数实参时报错。并不是加了const就意味着实参必须是常量,这个是我之前的误解。但是加了const意味着这个参数只能用于输入。
template<class type>
vec<type>::vec()
{
	_begin=NULL;
	_size=0;
}

template<class type>
vec<type>::vec(unsigned int size,const type& data)//插入size个元素,每个元素的值为data
{
	_size=size;
	_begin=NULL;
	_begin=(type*)malloc(sizeof(type)*size);//这里暂时用C语言的手动分配堆空间的函数 后面可能会自己设计一个内存池接口,取代它
	if(_begin!=NULL)//分配内存失败时,返回空指针,需要做异常处理
	{
		for(unsigned int i=0;i<size;i++)
		{
			_begin[i]=data;
		}
	}
	else
	{
		cout<<"vec init error!"<<endl;//
	}
}

template<class type>
vec<type>::vec(const vec& copy)//拷贝构造函数  这里形参必须是引用变量 否则会无限构造对象 死循环
{
	this->_size=copy->_size;
	this->_begin=copy->_begin;
}

template<class type>
vec<type>::~vec()//释放_begin指向的内存空间
{
    free(_begin);
}

template<class type>
unsigned int vec<type>::size()
{
	return _size;
}

template<class type>
void vec<type>::push_back(const type& data)
{
	_size++;//数组元素个数+1
	_begin=(type*)realloc(_begin,_size*sizeof(type));//数组大小变了 这里要重新分配内存空间
	if(_begin!=NULL)//分配内存失败需要异常处理
	{
		_begin[_size-1]=data;
	}
	else
	{
		cout<<"push_back error!"<<endl;
	}
}

template<class type>
void vec<type>::pop_back()
{
	_size--;
	_begin=(type*)realloc(_begin,_size*sizeof(type));
	if(_begin==NULL)
	{
		cout<<"pop_back error!"<<endl;
	}
}

template<class type>
type& vec<type>::operator[](unsigned int i)//返回引用变量是为了让它可以成为‘=’的左操作数,即可以用下标操作,改变元素的值
{
	if(i<_size && i>=0)//要防止下标越界  
	{
		type& tmp=_begin[i];
		return tmp;
	}
	else
	{
		type& tmp=_begin[0];
		cout<<"operator++ error!"<<endl;
		return tmp;
	}
}

//下面是测试用的main函数  常规操作已经实现  但是定义二维数组会有问题 比如vec<vec<int>> ,会达不到想要的效果 

int main()
{
	vec<int> me(5,2);
	cout<<"first test:"<<endl;
	for(vec<int>::iter i=me.begin();i!=me.end();i++)//用迭代器遍历
	{
		cout<<(*i)<<endl;
	}


	cout<<"second test:"<<endl;
	me.push_back(4);
	for(int i=0;i<me.size();i++)//用下标遍历
	{
		cout<<me[i]<<endl;
	}


	cout<<"third test:"<<endl;
	me.pop_back();
	me[1]=6;
	for(vec<int>::iter i=me.begin();i!=me.end();i++)
	{
		cout<<(*i)<<endl;
	}


	system("pause");
	return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值