在 C++ 编程中,栈是一种常用的数据结构,具有后进先出(LIFO)的特点。今天,我将向大家介绍一个自定义的动态栈类,它使用动态内存分配来实现栈的功能,并且具备自动扩展容量的能力。
类的定义与构造函数
我们的栈类名为 Stack,它有三个私有成员变量:mpstack 是指向整数数组的指针,用于存储栈中的元素;mptop 表示栈顶位置;mpcap 表示栈的当前容量。
在构造函数中,我们接受一个参数 num,默认值为 10,用于设置栈的初始容量。如果传入的 num 小于等于 0,我们抛出异常 "非法内存大小"。然后,我们使用 new 运算符分配一个大小为 num 的整数数组,并初始化 mptop 为 0,mpcap 为 num。
深拷贝构造函数
为了确保当栈一个对象被复制时,新对象拥有独立的内存空间,我们定义了深拷贝构造函数。它复制源对象的 mptop 和 mpcap 值,然后分配新的内存空间,并使用 std::copy 函数将源对象的元素复制到新分配的内存中。
析构函数
在析构函数中,我们使用 delete[] 运算符释放动态分配的内存,以避免内存泄漏。
拷贝赋值运算符重载
我们重载了等于运算符,以实现对象之间的赋值操作。在赋值过程中,我们首先检查自赋值的情况,避免不必要的操作。然后,我们分配新的内存空间,复制源对象的元素,并释放旧的内存,最后更新当前对象的 mptop、mpcap 和 mpstack 指针。
栈的基本操作
-
入栈(push) :在入栈操作中,我们首先检查栈是否已满,如果满了则调用 expand 函数扩展栈的容量。然后,将元素添加栈到顶,并递增 mptop。
-
出栈(pop) :出栈操作会检查栈是否为空,如果为空则抛出异常。否则,将 mptop 递减,模拟元素出栈。
-
取栈顶元素(top) :我们提供了两个版本的 top 函数,一个常量成员函数返回栈顶元素的常量引用,另一个非常量成员函数返回栈顶元素的引用,以便在需要时可以修改栈顶元素。在获取栈顶元素之前,我们检查栈是否为空。
判与空获取栈大小
empty 函数用于判断栈是否为空,如果 mptop 为 0 则返回 true,否则返回 false。size 函数返回栈的当前大小,即 mptop 的值。
栈的扩展(expand)
expand 函数用于在栈满时扩大栈的容量。默认情况下,栈的容量会扩大为原来的两倍。我们首先检查传入的扩展倍数 n 是否合法,然后计算新的容量 newmpcap。为了避免整数溢出,我们检查 newmpcap 除以 n 是否原来的等于容量 mpcap。接着,我们分配新的内存空间,将原有元素复制到新内存中,释放旧内存,并更新 mpcap 和 mpstack。
这个自定义的动态栈类在功能上较为完善,能够满足大多数栈操作的需求。在实际使用中,你可以根据需要进一步扩展或修改这个类,以适应不同的应用场景。希望这篇博客对你理解 C++ 中的栈实现有所帮助。
class Stack
{
public:
Stack(int num = 10)//构造函数
{
if (num <= 0)throw "非法内存大小";
mpstack = new int[num];
mptop = 0;
mpcap = num;
}
Stack(const Stack& other)//深拷贝函数
{
mptop = other.mptop;
mpcap = other.mpcap;
mpstack = new int[mpcap];
std::copy(other.mpstack, other.mpstack + other.mptop, this->mpstack);
}
~Stack()//析构函数
{
delete[] mpstack;
}
Stack& operator=(const Stack& other)//重载等于函数
{
if (&other == this)return *this;//防止相同导致释放同一块内存
int newmptop = other.mptop;
int newmpcap = other.mpcap;
int*newmpstack = new int[newmpcap];
std::copy(other.mpstack, other.mpstack + other.mptop, newmpstack);
delete[] mpstack;
mpstack = newmpstack;
mpcap = newmpcap;
mptop = newmptop;
return *this;
}
void push(int val)//入栈
{
if (mptop == mpcap)expand();
mpstack[mptop++] = val;
}
void pop()//出栈
{
if (mptop == 0)throw "非法内存";
else mptop--;
}
const int& top()const//取栈顶
{
if (mptop == 0)throw "非法内存";
else
{
return mpstack[mptop - 1];
}
}
int& top()//取栈顶
{
if (mptop == 0)throw "非法内存";
else
{
return mpstack[mptop - 1];
}
}
bool empty()//判空
{
if (mptop == 0)return true;
else return false;
}
int size()//返回栈的大小
{
return mptop;
}
void expand(int n = 2)//扩大函数
{
if (n <= 0)throw "非法";
int newmpcap = n*mpcap;
if (newmpcap / n != mpcap)throw "非法";//防止整数溢出
int* temp = new int[newmpcap];
std::copy(mpstack, mpstack + mptop, temp);
delete[] mpstack;
mpstack = temp;
mpcap = newmpcap;
}
private:
int* mpstack;
int mptop;//栈顶位置
int mpcap;//空间大小
};