构造函数和析构函数
根据OOP思想 实现一个顺序栈:
class SeqStack
{
public:
void init(int size = 10)//初始化
{
_pstack = new int[size];
_top = -1;
_size = size;
}
void release()//释放对象成员变量占用的外部堆内存(外部资源)
{
delete[]_pstack;//释放数组内存
_pstack = nullptr;//防止野指针
}
void push(int val)
{
if (full())
{
resize();
}
_pstack[++_top] = val;
}
void pop()
{
if (empty())
return;
--_top;
}
int top()
{
return _pstack[_top];
}
bool empty() {
return _top == -1; }
bool full() {
return _top == _size - 1; }
private:
int *_pstack;//动态开辟数组,存储顺序栈的元素
int _top;//栈顶元素的位置
int _size;//栈的总大小
void resize()//不是给用户用的,防止用户使用,所以定义为私有
{
int *tmp = new int[_size * 2];
for (int i = 0; i < _size; i++)
{
tmp[i] = _pstack[i];
}
/*
为什么不用memcpy(tmp, _pstack, sizeof(_size));realloc???
memcpy,realloc如果是拷贝数据时,可以用,但是如果拷贝对象就不一定正确了
*/
delete[]_pstack;
_pstack = tmp;
_size *= 2;
}
};
int main()//
{
SeqStack s1;
s1.init(5);//初始化——手动调用
for (int i = 0; i < 15; ++i)
{
s1.push(rand() % 100);//给这个栈添加上15个元素
}
while (!s1.empty())
{
cout << s1.top() << " ";
s1.pop();
}
s1.release();//释放对象成员变量占用的外部堆内存(外部资源)——手动调用
return 0;
}
其中热resize函数之所以定义在私有成员里,主要目的就是,防止用户使用,所以定义为私有。因为如果用户可以任意使用的话可能会造成间接更改私有成员变量。
同时,里面为什么用for循环?为什么不用memcpy()或者realloc()?
答:memcpy和realloc这里涉及的都是内存的拷贝,在对象里面并不适合。因为对象里面可能存在指针会调用外部内存,单纯的内存拷贝,会造成不同指针指向同一块内存。但是在这里其实是没有问题的,因为数组是在栈上,栈里面的内容存的都是整型,可以做内存的拷贝。
除此之外,上面的代码还存在一些问题,release()调用函数虽然在堆上new的资源被释放了,但是手动调用这个在使用中容易遗忘!!!!!
所以为了解决这个问题,就引入构造函数(自动进行初始化)和析构函数(自动释放资源),
构造函数和析构函数:
1 函数的名字和类名一样;
2 没有返回值;
3 代替了对象的成员变量的初始化操作; 对象不使用了,出作用域之前 把对象占用的外部资源都进行释放。(此时的 指针指向了初始化时候开辟的堆上的一块资源)
class SeqStack
{
public:
SeqStack(int size = 10)//构造函数,可以带参数,因此可以提供多个构造函数,形成函数重载
{
cout << this << " SeqStack() " << endl;
_pstack = new int[size];
_top = -1;
_size = size;
}
~SeqStack()//析构函数,是不带参数的,所以析构函数只能有一个
{
cout << this << " ~SeqStack() " << endl;
delete[]_pstack;
_pstack = nullptr;
}
void push