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;

1
2
3
4
5
6
7
~B
~A
END0
15
31
8
12

flag=1;

1
2
3
4
5
6
7
~B
~A
END0
4069160
31
8
12

flag=2;

1
2
3
4
5
6
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

1
2
3
4
5
6
7
8
~B
~A
END0
15
31
8
12
~A

flag=1

1
2
3
4
5
6
7
8
~B
~A
END0
3807016
31
8
12
[段错误]

调试发现段错误发生在代码的58行,即delete b这句。是不是有点感觉了。

flag=2;

1
2
3
4
5
6
7
8
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时,这里就皆大欢喜了。没什么可说的。

所以,我们的结论就在这里停住了,貌似三个代码都表明,虚析构函数的第二个是本类的析构函数,其它等我再写个复杂点的代码,中间有指针申请空间的那种,这个在栈里玩的代码,估计是很难引起段错误。

照例内存图示画一个,如下:

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 照相把脸照的很长怎么办 小猫咪下半身不能动不吃不喝怎么办 画个火柴人2主页面进不了怎么办? 火柴人联盟2的衣厨怎么办 偶尔犯了一次错误很自责怎么办 房间已经装修好但想加线条怎么办 自己的房间特别乱却不想收拾怎么办 素描中当阴影面正对着自己怎么办 相爱的俩个人却不能在一起怎么办 苹果手机爱思助手下不了东西怎么办 苹果手机在爱思助手刷坏了怎么办 美团外卖摔坏我的奶茶怎么办 米兔定位电话头像突然调换了怎么办 还在气头上时孩子就来撒娇了怎么办 老公把老婆微信屏蔽了老婆该怎么办 魅族手机有质量问题不给退款怎么办 屏幕点不动锁屏密码无法点怎么办 在嘴巴和鼻翼周围长痘该怎么办 小孩嘴巴被蚊虫咬的红肿怎么办 每次洗头都掉好多头发该怎么办 关于宝宝脾不好胃口却很好怎么办 高中生掉发严重怎么办该看什么科 脱头发如何治疗 掉头发厉害怎么办 头发上突然秃了一小块怎么办 全秃过后长出来白色头发怎么办 高三学生喜欢打球影响学习怎么办 高三学生受同学搔挠学习怎么办 烫完头发掉头发很厉害怎么办 烫头发后掉头发很厉害怎么办 十八岁了下门牙活动疼痛怎么办 烫完头发后掉头发很厉害怎么办 16岁的孩孑得了肺炎怎么办 我的头发掉的很厉害怎么办 八个月宝宝头后面没头发怎么办 生完孩子掉头发很厉害怎么办 生完孩子后掉头发很厉害怎么办 头发又细又软又卷怎么办 后颈部没有头发掉光了想植发怎么办 头发掉的厉害怎么办怎么拯救掉头发 头发可以种植吗 如果是秃顶怎么办 染头发把手指甲染黑了怎么办