- 函数的名字和类名一样
- 没有返回值
- 定义了对象,自动调用构造函数,出作用域自动调用析构函数;代替了对象成员变量的初始化操作和对象出作用域之前把资源释放掉。
- 栈上的对象 先构造的后析构,后构造的先析构(相当于是入栈出栈的过程)
构造函数: 定义对象时,自动调用的;可以重载的;构造完成,对象产生了 析构函数: 不带参数,不能重载,只有一个析构函数;析构完成,对象就不存在了 .data上的对象 定义的时候构造,程序结束时析构 heap上的对象 new的时候构造 delete的时候析构 stack上的对象 进入函数到它定义的地方构造,出函数作用域析构
delete堆上对象时,先调用对象的析构函数,再见堆上的内存释放掉。
#includeusing namespace std; class SeqStack { public: //构造函数 SeqStack s1; SeqStack s2(20); 开辟资源 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(int val)//入栈 { if (full()) resize(); _pstack[++_top] = val; //初始 _top = -1; } 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]; }//为什么不用memcpy(ptmp, _pstack, sizeof(int)*_size); 或者realloc? //因为这些涉及的是内存拷贝 ,在对象里面不适合 delete[]_pstack; _pstack = ptmp; _size *= 2; } }; SeqStack gs;//全局的对象,定义的时候构造,等程序结束的时候才析构,在数据段上 int main() { SeqStack* ps = new SeqStack(60); //new的操作:malloc在堆上内存开辟+SeqStack(60)对象构造 ps->push(70); ps->push(80); ps->pop(); cout << ps->top() << endl; delete ps; //堆上的对象要我们手动释放,先调用ps->~SeqStack()+然后free(ps) 这是delete和free的区别 //定义一个对象有两件事情:1.开辟内存 2.调用构造函数 SeqStack s;//调用默认的无参的构造函数 //s.init(5); //对象成员变量的初始化操作 for (int i = 0; i < 15; ++i) { s.push(rand() % 100); } while (!s.empty()) { cout << s.top() << " "; s.pop(); } //s.release();//释放对象成员变量占用的外部堆内存(外部资源) SeqStack s1(50);//也可以这样定义栈,初始化为50,因为有整型参数的构造函数,出main函数自动析构 s1.~SeqStack();//析构函数可以自己调用,因为对象还在,但是调用以后,我们就说对象不存在了,但是内存还在 s1.push(30);//析构函数调用完之后,编译没有问题,但是这样做,就是堆内存的非法访问了!!! //不建议自己去调用析构函数 return 0; }



