模板栈(三)

1. 判满函数full()与得到容器容量函数capacity()

template<class Type>
class SeqStack
{
private:
	Type *data;   //指向所存储的数据
	int maxsize;  //栈容量
	int pos;      //栈顶
public:
	size_t capacity() const //得到容器的容量大小
	{
		return maxsize;
		//注意:前面两个模块栈容量所使用的是capacity,为与函数名区别,本模块使用的是maxsize;
	}
	bool full() const//判断容器是否已满
	{
		//通过比较栈的容量与栈中对象个数是否相等
		return size() == capacity();
	}
};

注意:函数名与成员数据名不能相同。

2. 入栈push()函数

在数据进行入栈时,可能会出现栈满情况,因此需要在push函数中添加判满以及增容函数。

bool IncSize()
{
	size_t oldlen = size();                             //保存原有数据个数
	size_t newlen = oldlen*2;                           //新的容量
	Type *newdata = (Type*)malloc(sizeof(Type)*newlen); //申请空间
	if(newdata == NULL)
	{
		return false;                                   //申请空间失败,返回false
	}
	for(int i = 0;i<oldlen;i++)                         //遍历原有数据个数
	{
		//通过定位new,调用带参数的构造函数,创建对象并赋值
		new(&newdata[i] Type(data[i]);
	}
	for(int i = 0;i<oldlen;i++)                        //遍历原有数据个数
	{
		//调用析构函数,释放资源
		(&data[i])->~Type();
	}
	free(data);                                       //释放原有空间
	data = newdata;                                   //将新的data指向赋值给原始data
	maxsize = newlen;                                 //最大容量变为新的容量
	return true;
}
void push(const Type &x)
{
	if(full() && !IncSize())                          //若栈空间已满并且增容失败时,返回失败
	{
		exit(EXIT_FAILURE);
	}
	new(&data[++pos]) Type(x);                        //其余情况进行入栈
}

总结:

  1. 增容函数应写在push函数外,便于push函数的阅读性;
  2. 对于一些使用者不需要了解的函数,应该将这类函数设置为私有函数,例如:增容函数应设置为私有函数,调用者并不需要了解函数如何增容,并且还可以防止栈空间还充足的情况下,调用增容函数进行增容。

3. 拷贝构造函数SeqStack(const SeqStack &seq)

拷贝构造函数需要注意:

//错误做法:
SeqStack(const SeqStack &seq)
	:data(seq.data),maxsize(seq.maxsize),pos(seq.pos)
{}

注意:
对于栈中的元素不能直接进行赋值,也就是不能对象赋值给空间,需要通过定位new调动构造函数,从而创建对象并进行赋值。
正确的拷贝构造函数如下:

//正确做法:
SeqStack(const SeqStack &seq)
	:data(NULL),maxsize(seq.maxsize),pos(seq.pos)
{
	if(seq.data != NULL)
	{
		data = (Type *)malloc(sizeof(Type)*maxsize)   //首先申请空间
		if(data == NULL) exit(EXIT_FAILURE);          //判断是否申请空间成功
		for(int i = 0;i<pos;i++)                      //遍历栈中元素
		{
			//通过定位new,调动构造函数,创建对象并进行赋值。
			new(&data[i]) Type(seq.data[i]);
		}
	}
}

4. 赋值函数SeqStack & operator=(const SeqStack &seq)

赋值函数同拷贝构造函数需注意:

//错误做法:
SeqStack & operator=(const SeqStack &seq)
{
	if(this != &seq)           //不能自己赋值自己,无意义
	{
		data = seq.data;       //直接将元素进行赋值
		maxsize = seq.maxsize;
		pos = seq.pos;
	}
	return *this;
}

注意:
赋值函数和拷贝构造函数一样,不能够直接进行赋值,不能够对空间进行赋值,需要通过定位new,调动构造函数,创建对象,从而进行赋值。
正确做法如下:

SeqStack & operator=(const SeqStack &seq)
{
	if(this != &seq)                //不能自己复制自己,无意义
	{
		for(int i=0;i<pos;i++)      //遍历元素
		{
			//将原有的元素进行析构,是否资源
			(&data[i])->~Type();
		}
		free(data);                //释放空间
		maxsize = seq.maxsize;     //seq的容量、pos可以直接赋值
		pos = seq.pos;
		data = (Type *)malloc(sizeof(Type)*maxsize);  //首先申请空间
		if(data == NULL) exit(EXIT_FAILURE);          //判断申请空间是否失败
		for(int i=0;i<pos;i++)                        //遍历元素
		{
			//通过定位new,调用构造函数,创建对象,并进行赋值
			new(&data[i]) Type(seq.data[i]);
		}
	}
	return *this;
}

本次简单的模板栈优化程序将进行到此步骤,若程序中有错误编写或其他优化程序请联系我,相互交流。
感谢大家的阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值