c++对象内存模型之虚析构函数篇(3)
来源:互联网 发布:踪迹谋杀之谜类似知乎 编辑:程序博客网 时间:2024/05/17 01:55
经过前两篇的分析,说实话, 现在的我是比较晕的。但仍然坚持自己的学习方法,先自己“理所当然”的理解,再去求证官方说法。毕竟东西是别人定的,规则是别人的。
1 http://www.cnblogs.com/boota/p/4040310.html2 http://www.cnblogs.com/boota/p/4043282.html
这次是讨论的情形是:有继承关系,单一继承,父类有虚析构函数。(子类有没有虚析构函数不影响,这个结论可以验证,就不另做讨论)
上代码:
1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 int ia; 8 9 A ():ia(15)10 { 11 } 12 virtual ~A ()13 {14 cout << "~A" << endl;15 } 16 virtual void f()17 {18 cout << "A:f()" <<endl;19 } 20 };21 22 class B : public A23 {24 public :25 int ib;26 27 B():ib(31){}28 virtual ~B()29 {30 cout << "~B" << endl; 31 } 32 virtual void f()33 {34 cout << "B:f()" << endl; 35 }36 37 };38 39 typedef void (*F)();40 41 int main()42 {43 44 F pf = NULL;45 B *b = new B();46 int **p = (int **)b;47 48 int flag = 2 ;49 pf = (F)p[0][flag];50 pf();51 52 cout << "END"<<p[0][3] << endl;53 cout << b->ia << endl;54 cout << b->ib << endl;55 56 cout << sizeof(A) << endl;57 cout << sizeof(B) << endl;58 }
程序输出 :
flag=0;
~B
~A
END0
15
31
8
12
flag=1;
~B
~A
END0
4069160
31
8
12
flag=2;
B:f()
END0
15
31
8
12
分析:
说实话,自己在这里真不知道该怎么分析了。于是在程序最后面加了一个delete b,貌似得见云开见明月,貌似。。。
见代码
1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 int ia; 8 9 A ():ia(15)10 { 11 } 12 virtual ~A ()13 {14 cout << "~A" << endl;15 } 16 virtual void f()17 {18 cout << "A:f()" <<endl;19 } 20 };21 22 class B : public A23 {24 public :25 int ib;26 27 B():ib(31){}28 virtual ~B()29 {30 cout << "~B" << endl; 31 } 32 virtual void f()33 {34 cout << "B:f()" << endl; 35 }36 37 };38 39 typedef void (*F)();40 41 int main()42 {43 44 F pf = NULL;45 B *b = new B();46 int **p = (int **)b;47 48 int flag = 2 ;49 pf = (F)p[0][flag];50 pf();51 52 cout << "END"<<p[0][3] << endl;53 cout << b->ia << endl;54 cout << b->ib << endl;55 56 cout << sizeof(A) << endl;57 cout << sizeof(B) << endl;58 delete b;59 }
输出:
flag=0
~B
~A
END0
15
31
8
12
~A
flag=1
~B
~A
END0
3807016
31
8
12
[段错误]
调试发现段错误发生在代码的58行,即delete b这句。是不是有点感觉了。
flag=2;
B:f()
END0
15
31
8
12
~B
~A
这下可以写点分析了,不然冏死了。
flag=0时,先执行了虚函数表第一个元素指定的析构函数,对后面的影响是delete语句只执行了A的析构函数,这说明第一个元素是B的析构函数,尼玛,为什么数据ia,ib都没有变???理论上来说,A有虚析构函数,delete b这句是应该输出~B\n~A\n,此时由于先执行了虚函数表中第一个函数,delete只执行了A的析构函数,说明b已经退化成指向A的对象的指针。数据没变,不过数据是合法的,这个可以写个复杂点的类来验证。综上,是不是可以得出第一个析构函数,靠,不知道干嘛的,存疑。
flag=1时,就很正常了。段错误也有了,数据显示不正常,再加上输出也是执行B与A的析构函数的效果,充分说明虚函数表第二个元素就是B的析构函数。这里再猜一次,第一个是A的,或者只是一个效果,表明是A的子类,so还是不知道干嘛的。
flag=2时,这里就皆大欢喜了。没什么可说的。
所以,我们的结论就在这里停住了,貌似三个代码都表明,虚析构函数的第二个是本类的析构函数,其它等我再写个复杂点的代码,中间有指针申请空间的那种,这个在栈里玩的代码,估计是很难引起段错误。
照例内存图示画一个,如下:
- c++对象内存模型之虚析构函数篇(3)
- C++对象模型之函数成员(3)
- C语言提高之技术模型层次、学习标准、特点、内存四区、函数调用模型
- 【C++】C++对象内存模型简介
- 漫谈C++:对象内存模型分析
- C++-对象继承内存模型配图
- C++学习之C++对象内存模型(上)
- C++学习之C++对象内存模型(下)
- JavaEE程序猿之对象的内存模型(17)
- C++ - 对象模型之 内存布局
- vlc之vlc_object_t对象的内存模型
- c++对象内存模型(内存布局)
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- Data语意学之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- [置顶] 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- C++对象模型之函数成员(1)
- C++对象模型之函数成员(2)
- 关于如何在非微软平台上建立高信任的SharePoint应用程序
- windows apache虚拟机配置
- 报表系统遇到的困难
- 第四章:数据类型转换——深入浅出学Spring Web MVC
- 英语学习
- c++对象内存模型之虚析构函数篇(3)
- 诊断索引健全性的新工具
- Windows系统下Ant自动编译打包并签名Android应用——实践篇
- 第五章:数据格式化——深入浅出学Spring Web MVC
- android反射组件 (一)java 自定义annotation基础知识
- map的查找,用find, 别用中括号
- 消息适配器
- C实现通用数据结构--双向链表
- 单精度与双精度的区别