c++构造函数和析构函数调用规则
来源:互联网 发布:java ioc原理 编辑:程序博客网 时间:2024/06/04 19:11
先看如下程序
/*coding by:ygqwanin 2013 / 08 / 20*/#include <iostream>#include <cstring>#include <algorithm>using namespace std;class Test{public:Test(int a):a(a){cout << "创建对象 : " << a << endl;}~Test(){cout << "销毁对象 : " << a << endl;}int a;};int main(){Test a(1);Test b(2);Test c(3);Test *d = new Test(4);Test *e = new Test(5);Test *f = new Test(6);cout << "--------------------" << endl;delete e;delete d;delete f;cout << "++++++++++++++++++++" << endl;return 0;}
创建对象 : 1
创建对象 : 2
创建对象 : 3
创建对象 : 4
创建对象 : 5
创建对象 : 6
--------------------
销毁对象 : 5
销毁对象 : 4
销毁对象 : 6
++++++++++++++++++++
销毁对象 : 3
销毁对象 : 2
销毁对象 : 1
请按任意键继续. . .
可以从运行结果看出, 用new运算符在堆上面开辟的空间跟delete的调用顺序有关
而直接在栈上面开辟的空间的调用规则却是固定的, 还是跟创建的顺序有关,为什么会这样呢?
看了下资料研究了下栈开辟空间的规则后发现是:
栈开辟空间:编译器生成代码在线程栈中移动指针开辟空间
栈销毁空间: 一样的道理, 只是这次移动的顺序是反着移动, 所以就跟生成空间的顺序相反, 那么结果就能够解释了
重点看看在堆上操作空间:
开辟: new一下的时候从全局堆中开辟了空间(这个开辟的算法我不清楚)然后赋值给栈内的指针d, 也就是说编译器一共开辟了两个空间, 空间一是在线程栈中生成一个指针, 空间二是在全剧堆中开辟一个对象空间; 并且栈空间中的指针指向堆空间的地址
销毁: 当delete d;的时候首先是销毁d指向的堆空间的地址里面的数据(怎么销毁的我也不知道), 然后没然后了
当d的作用于到了之后再由编译器自动销毁栈中的指针d;需要注意的是在销毁完d所指向的堆内空间时, d依然是指向那个堆空间的, 但是这个时候用d会出现错误的;
上面的这个错误是很严重的bug:
情况1: d 所指向的空间被系统收回去了, 这个时候d访问的是非法空间, 程序崩溃
情况2: d所指向的空间是别的对象的空间, 那么这个对d的后续操作有影响, 更不得了的是对那个堆内的数据可能照成破坏, 所以bug很严重的, 必须小心呀
情况3:跟2很想, 貌似我不太懂, 就不说了
- c++构造函数和析构函数调用规则
- [C++]显示调用构造函数和析构函数
- 构造函数和析构函数的构造规则
- 构造函数调用规则研究
- C++构造函数调用规则
- 构造函数的调用规则
- 构造函数的调用规则
- 《Effective C++》不要在构造函数和析构函数中调用虚函数
- 构造函数和析构函数【c++】
- [c++]构造函数和析构函数
- 【C#】构造函数和析构函数
- 【C++】构造函数和析构函数
- 【C++】构造函数和析构函数
- C++:构造函数和析构函数
- 构造函数和析构函数中的虚函数调用
- 构造函数和析构函数中的虚函数调用
- 构造函数和析构函数内部调用虚函数
- 派生类构造函数和析构函数的调用顺序(C++)
- 【让你操作Windows于弹指之间§小米跟你说】
- css 背景
- Android(Java):在textview中显示富文本
- Linux:Clock skew detected. Your build may be incomplete.解决办法
- Java以utf8保存为文本文件
- c++构造函数和析构函数调用规则
- 很详细的Jquery 操作Table
- DWR使用总结
- opencv中cvCalibrateCamera2()的函数细解
- windows7 下安装MongoDB
- eclipse “ Failed to load the JNI shared library……jvm.dll” 解决方案
- 学长谈面试经验
- CVPR 2013 reading list
- hdu 1867 A + B for you again