请先看代码:

 
  
  1. #include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4.  
  5. class A  
  6. {  
  7. public:  
  8.     A()  
  9.     {  
  10.         m_a=1;  
  11.         m_b=2;  
  12.     }  
  13.     ~A()  
  14.     {  
  15.  
  16.     };  
  17.     void fun()  
  18.     {  
  19.         printf("%d%d",m_a,m_b);  
  20.     }  
  21. public:  
  22.     int m_a;  
  23.     int m_b;  
  24. };  
  25.  
  26. class B  
  27. {  
  28. public:  
  29.     B()  
  30.     {  
  31.         m_c=3;        
  32.     }  
  33.     ~B()  
  34.     {  
  35.           
  36.     };  
  37.     void fun()  
  38.     {  
  39.         printf("%d\n",m_c);  
  40.     }  
  41. public:  
  42.     int m_c;  
  43. };  
  44.  
  45. int main()  
  46. {  
  47.     A a;  
  48.     B* pb=(B*)&a;  
  49.     cout<<&a<<endl;          //输出a对象的地址  
  50.     cout<<&(a.m_a)<<endl;    //输出a对象数据成员m_a的地址  
  51.     printf("%p\n",&A::m_a);  //输出a对象数据成员m_a相对于a对象的偏移地址  
  52.     printf("%p\n",&A::m_b);  //输出a对象数据成员m_b相对于a对象的偏移地址  
  53.     printf("%p\n",&B::m_c);  //输出类B数据成员m_b相对于类B的偏移地址  
  54.     pb->fun();                 
  55.     return 0;  

运行结果:

解释:难点在于内存偏移问题的理解

B* pb = (B*)(&a);这是一个野蛮的转化,强制把a地址内容堪称是一个B类对象,pb指向的是a类的内存空间:pb->fun();正常情况下,B类只有一个元素int m_c,但是a类的内存空间中存放第一个元素的位置是m_a,pb指向的是对象的内存地址,上例为0012FF6C,当pb->fun()调用B::fun()来打印m_c时,编译器对m_c的认识就是m_c距离对象的偏移量0,于是打印了对象a首地址的偏移量0012FF6C+0变量的值,所以pb->fun()打印的是m_a的值1;