金山的一道面试题(考察面向对象和内存模型)

 请问程序会输出什么结果:

  1. #include <stdio.h>
  2. class A
  3. {
  4. public:
  5.     A() {m_a = 1; m_b = 2;}
  6.     ~A(){};
  7.     void fun(){printf("%d%d", m_a,m_b);}
  8. private:
  9.     int m_a;
  10.     int m_b;
  11. };
  12. class B
  13. {
  14. public:
  15.     B(){m_c = 3;}
  16.     ~B();
  17.     void fun() {printf("%d", m_c);}
  18. private:
  19.     int m_c;
  20. };
  21. void main()
  22. {
  23. A a;
  24. B *pb = (B*)(&a);
  25. pb->fun();
  26. }

 

在VC 6.0的编译环境下,输出的是 1. 

 

个人认为:

     类的内存分配方式和模型都是相同的。通过(B*)(&a);的强制类型转换,把指针B类的指针pb指向类A a这块临时栈内存中。 

      因为类成员函数的地址是写在静态存储区的。所以这个时候 pb->fun();调用的还是 类B中的fun(); 接着,fun()访问m_c变量的值。

      因为前面发生了强制类型转换。所以fun()读取m_c值的时候,实际上是读取A a临时变量在栈中分配的内存。而栈的分配是按照类成员变量顺序来分配的。第一个是int类型的变量就是最前面四个字节,第二个是char的,那么就是第5个字节。类似这样。。 那么这时候读取 m_c 实际上就是读的类A临时变量a的堆栈的前四个字节(因为m_c和m_a都是第一个成员变量。它们的内存是匹配的)。所以m_c的值看起来是等于m_a。实际我们访问的是m_a的值。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值