模板栈(三)
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); //其余情况进行入栈
}
总结:
- 增容函数应写在push函数外,便于push函数的阅读性;
- 对于一些使用者不需要了解的函数,应该将这类函数设置为私有函数,例如:增容函数应设置为私有函数,调用者并不需要了解函数如何增容,并且还可以防止栈空间还充足的情况下,调用增容函数进行增容。
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;
}
本次简单的模板栈优化程序将进行到此步骤,若程序中有错误编写或其他优化程序请联系我,相互交流。
感谢大家的阅读!