您的位置:首页 > 其它

派生类指针方法获取基类的函数

2011-02-13 15:00 225 查看
派生类指针方法获取基类的函数,在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)

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐