1 c++五大区是基本概念
栈,堆,常量,静态,程序区
所以
你得区分java和c++定义对象时,内存分配的基本区别
对于java来说,定义内存,就只有一种方式
Test test = new Test();
其中test存放到栈区,此时的test仅仅只是引用,也就是(替身),而new Test()这个对象存放到堆区
对于c++,情况要复杂得多
c++的定义存在两种情况
情况一:Test test;
Box box;
box.height = 22;
box.width = 10;
box.length = 30;
cout<<"sum of box ="<<box.sum()<<"\n";
这种情况下,test存放到栈区,并直接执行构造函数,也就是说,此时的test本身即为对象而非引用
情况二: Test *test = new Test();
这种情况下,*test存放到栈区,而new Test()存放到堆区,这个和java就很像了。
Box *box2 = new Box();
box2->height = 22;
box2->width = 10;
box2->length = 30;
cout<<box2->sum();
那么我们知道,一个函数运行完,会自动释放掉这一组栈的内存,所以,如果我要定义一个持久的,共享的数据,我一般,存在两个选择,一个是堆对象(基于指针的方式)一种是栈对象
当然,使用指针创建固然看起来很爽,但很多时候会出现两个问题
1.内存泄露:分配了对象的内存,但是忘记释放
2.悬挂指针:释放了对象的内存,但是指针未置Null
另外,如果我们选择共享对象的方式是指针(我们称为堆对象),但是,如果我们选择共享对象为栈对象,那么能否去引用这个栈对象呢?我们对栈的理解,都是后进先出,最多处理栈顶和栈尾,那么处于栈中的数据,是否能够引用?
答案是支持的,甚至是自动的,所以使用栈对象看起来更加安全。
我们搜索了一下博客,关于栈全局对象的释放:
https://blog.csdn.net/qq_45550375/article/details/106482650
我们发现:
对象的创建顺序是:全局对象->在方法中按顺序声明的对象
对象的析构顺序是:局部栈对象,手动释放的堆对象,局部静态对象,全局对象
我们发现,如果你不手动释放堆对象,它会不会执行析构...,至少在QT里面我没找到验证方式,我去vs试一下
你会发现,只有一个析构,所以,当你使用堆对象时,一定要注意,一定要回收,它...很危险!!!!!
这样看起来,使用共享对象的最佳方式是栈对象。
但是...你是否会思考一个新的问,临时对象,比如返回一个临时的栈对象,就会在栈区存在一个分配和释放的操作,这对于性能而言,其实是挺糟心的一件事,但...胜在安全,如果你是新手,其实更建议使用栈对象而不是堆对象哦~