首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

学习C++虚函数时的指针有关问题

2013-01-02 
学习C++虚函数时的指针问题在自学C++时看过许多博文,看到一篇博文中有如下:class Base {public:virtual vo

学习C++虚函数时的指针问题
在自学C++时看过许多博文,看到一篇博文中有如下:

class Base {
     public:
            virtual void f() { cout << "Base::f" << endl; }
            virtual void g() { cout << "Base::g" << endl; }
            virtual void h() { cout << "Base::h" << endl; }
 
};


typedef void(*Fun)(void);
 
            Base b;
 
            Fun pFun = NULL;
 
            cout << "虚函数表地址:" << (int*)(&b) << endl;
            cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl;
 
            // Invoke the first virtual function 
            pFun = (Fun)*((int*)*(int*)(&b));
            pFun();



自己想了却是如何也想不明白,我觉得 (int*)(&b) 应该是指向虚函数表的指针本身的地址,*(int*)(&b)是虚函数表的地址,(int*)*(int*)(&b)也是虚函数表的地址,*(int*)*(int*)(&b)是第一个函数地址,可是自己用vs测试时发现 *(int*)(&b)与(int*)*(int*)(&b)输出不同,而&b与(int*)(&b)却是相同的,

还有pFun()是具体如何调用了class Base 中f()函数的.



求大牛帮忙解答,越详细越好!!

[解决办法]
首先一点,vptr在对象模型的头还是尾,标准没有规定。因此,不同的compiler,这可能不同。据说,vc是放在头的。所以这个程序可以假设是在vc编译器下。

&b与(int*)(&b)肯定相同,都是vptr的地址,*(int*)(&b)就是vptr的内容,就是vtable地址。在有些compiler下,vtable的第一条是class的type info,但这里显然不是——可能是vc编译器的问题(vc的编译器就是诡异)。我们认为vtable的第一项就是第一个virtual function的地址,为了方便,设:

vptr = *(int*)(&b)

(int*)*(int*)(&b) = (int*)vptr

把vptr的内容转换成一个int*,可以看作一个int数组,就是vtable本身,即:

int vtable[M];

*(int*)vptr => *vtable => vtable[0]

也就是第一个virtual function的地址,后边把它转成了Fun来使用。

热点排行