派生类指针方法获取基类的函数,在vc2005下编译,不推荐使用因为不通的编译器内存结构不一样,只是加深对类的viutal table的理解及类的内存结构。 // Test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include<iostream> #include<vector> //有用么 // 头文件,使用stl 中的vector ,没用到vector可用可无 //#include"s.h" //有用么 // 如果没有用到s.h中的函数就可用可无。 using namespace std; class A { public: virtual void f(){cout<<"A::f";} virtual void g(){cout<<"A::g";} virtual void h(){cout<<"A::h";} }; class B { public: virtual void f(){cout<<"B::f";} virtual void g(){cout<<"B::g";} virtual void h(){cout<<"B::h";} }; class C { public: virtual void f(){cout<<"C::f";} virtual void g(){cout<<"C::g";} virtual void h(){cout<<"C::h";} }; class Son : public C , public B ,public A { }; typedef void (*Fun)(); int main() { Son son; Fun **pS; Fun pFun = NULL; pS= (Fun**)((&son+0)+0); pFun = pS[0][0]; cout<<"第1次pFun输出什么?"; pFun(); int n = sizeof(son); //楼主应该记错了,现在才是正确的,错误的原因是指针加减, //,(&son)+1 相等于把son的指针加12,(n = sizeof(son) = 12)指针指向无效区域,所有程序崩溃。所有要转换成int * ,指针向下加1. //改成下面就可以,估计是楼主记错了,要不出代码的人没有考虑到。 pFun = (Fun )*((int*)*(int*)(&son)+1+1); //pFun = (Fun)*((int*)*(int*)(&son + 1) + 1); // (int*)(&son) = 0x00417788 <=> p表示 //*(int*)(&son)+1 <=>*(p) + 1 = 0x0041778c; //(int*)*(int*)(&son)+1+1 <=> (int *)(0x0041778c) + 1 = 0x00417790; // (Fun) * (0x00417790)把地址0x00417790的值(0x00411203)取出来 ,类型强制转换成Fun. // 可以看到实际上是C::h(void) 。 主要是了解指针的加减法。 // pFun = (Fun )*((int*)*(int*)(&son+1)); cout<<"第2次pFun输出什么?"; pFun(); int m = sizeof(pS); // ps 把指针转化成二维数组。ps 的类型是FUN ** // 考察二维数组和指针的运算 。 ps[1][0] 其实就是 *(*(ps + 1)+ 0) // //pFun = pS[1][0]; pFun = *(*(pS + 1)+ 0); cout<<"第3次pFun输出什么?"; pFun(); //指针无效 //获取B的第四个函数(从0开始数),越界。 //pFun = pS[1][3]; //pFun = pS[1][2]; //pFun = *(*(pS + 1)+ 3); pFun = *(*(pS + 1)+ 2); cout<<"第4次pFun输出什么?"; pFun(); } /* class C的内存格式 ------- &s ==(0x00417788) f 地址((int*)(&son)) 存储值为(*((int*)(&son)+1)):[0] = 0x004110aa C::f(void) virtual table point (class c) -> g 地址((int*)(&son)+1) 存储值为:[1] = 0x00411177 C::g(void) h 地址((int*)(&son)+2) 存储值为:[2] = 0x00411203 C::h(void) ------- __vfptr = 0x00417774 f [0] = 0x004110af B::f(void) virtual talbe point (class b) -> g [1] = 0x0041102d B::g(void) h [2] = 0x004110ff B::h(void) ------- __vfptr = 0x00417760 f [0] = 0x00411276 A::f(void) vitrual table point (class a) -> g [1] = 0x0041115e A::g(void) h [2] = 0x004111c2 A::h(void) */