派生类指针方法获取基类的函数
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) */
相关文章推荐
- 派生类中基类成员函数的this指针
- C++中使用基类指针调用派生类中定义的方法
- 通过函数参数获取新创建指针的三种方法
- OJ——指向基类的指针访问派生类的成员函数
- 1.如何避免野指针2.获取字符串的两种方法。以及malloc,calloc,ralloc的使用注意点3.二维三维数组4.数组和函数的区别
- C++通过基类指针delete派生类数组,析构函数是虚函数,程序为什么会崩溃? https://www.zhihu.com/question/30838092/answer/49623765
- 多态继承情况下,有一个基类指针指向派生类对象,如何用它调用基类的虚函数?
- 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针
- C/C++中为什么在类外利用多态基类指向派生类指针可以调用类的私有成员函数?
- YTU-OJ-Problem J: B3 指向基类的指针访问派生类的成员函数
- C++中通过派生类调用第二基类的普通成员函数时this指针的调整
- 指向派生类对象的基类指针与虚函数
- [疑问]C/C++中为什么在类外利用多态基类指向派生类指针可以调用类的私有成员函数?
- 基类指针使用重载输入输出运算符函数操作派生类
- 基类函数的this指针和派生类函数的this指针
- 指向基类/派生类指针,指向基类成员/派生类成员指针,及互相赋值
- 类的成员函数指针的使用方法
- 关于通过不含虚析构函数的基类类型的指针删除派生类对象的问题
- DLL加载、获取函数指针。
- MFC各种指针句柄获取方法