这里写目录标题
说到构造函数和析构函数,你知道他们分别是什么,用来干什么的吗?首先我们用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* ptmp = new int[_size * 2];
for (int i = 0; i < _size; ++i)
{
ptmp[i] = _pstack[i];
}
delete[]_pstack;
_pstack = ptmp;
_size *= 2;
}
};
int main()
{
SeqStack s;
s.init(5);
for (int i = 0; i < 15; ++i)
{
s.push(rand() % 100);
}
while (!s.empty())
{
cout << s.top() << " ";
s.pop();
}
return 0;
}
运行结果如下:
但是看似完美的代码过后却有很多的问题。
- 面对众多的成员方法可能连你也会忘记自己到底写了哪些吧~例如,release方法就被我们全然忘记了。
- 仔细想一想,我们堆上开辟的内存还没有释放,这样很容易造成程序崩溃。所以每次都需要手动初始化对象以及对对象资源进行释放,
所有有什么好的方法解决这个问题呢,由此,我们引出了构造函数以及析构函数的概念。
1、深入理解构造函数和析构函数
构造函数和析构函数他们的函数的名字和类名一样,没有返回值。
1.1 构造函数
1、概念
主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
2、特点
允许重载
:是可以带参数的,因此可以提供多个构造函数- 系统提供默认的构造函数,但是一旦人为提供了构造函数,就不使用系统提供的默认构造函数
3、实例
就拿文章开头实现的栈的例子来说,其构造函数实现如下:
SeqStack(int size = 10)
{
cout << this << "SeqStack(