栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

172-C++进阶(构造和析构函数)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

172-C++进阶(构造和析构函数)

构造函数和析构函数
  • 函数的名字和类名一样
  • 没有返回值
  • 定义了对象,自动调用构造函数,出作用域自动调用析构函数;代替了对象成员变量的初始化操作和对象出作用域之前把资源释放掉。
  • 栈上的对象 先构造的后析构,后构造的先析构(相当于是入栈出栈的过程)
构造函数:
	定义对象时,自动调用的;可以重载的;构造完成,对象产生了
析构函数:
	不带参数,不能重载,只有一个析构函数;析构完成,对象就不存在了
.data上的对象  定义的时候构造,程序结束时析构
heap上的对象  new的时候构造 delete的时候析构
stack上的对象  进入函数到它定义的地方构造,出函数作用域析构

delete堆上对象时,先调用对象的析构函数,再见堆上的内存释放掉。

#include 
using 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;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/867422.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号