在有和没有咨询VM表的情况下通过指针调用虚函数

时间:2011-07-12 21:47:36

标签: c++ pointers virtual ansi

我想获取c ++类的成员函数的地址,将其存储在指针中,稍后调用虚函数。

我知道一些关于它的事情,但现在不知道如何获取虚拟函数的某个实现的地址,该虚函数不是最后代类(对象的实际类)的实现。

以下是一些示例代码:

    #include <iostream>

    using namespace std;

    class ca
    {
            public:
            virtual void vfunc() {cout << "a::vfunc ";}
            void mfunc() {cout << "a::mfunc ";}
    };

    class cb : public ca
    {
            public:
            virtual void vfunc() {cout << "b::vfunc ";}
    };

    extern "C" int main(int, char **)
    {
            void (ca:: *ptr_to_vfunc)() = &ca::vfunc;

            cout << sizeof(ptr_to_vfunc) << " ";

            cb b;

            (b.*ptr_to_vfunc)();

            ca a;

            (a.*ptr_to_vfunc)();

            void (ca:: *ptr_to_mfunc)() = &ca::mfunc;

            cout << sizeof(ptr_to_mfunc) << " ";
            (a.*ptr_to_mfunc)();
    }

输出结果为:

12 b :: vfunc a :: vfunc 12 a :: mfunc

我正在使用win32-environment,成员函数指针的大小是3 * 32位值!当我获取成员函数的地址时,我没有指定对象,但是,我的调用调用了最后代类的vfunc()实现。

1)这里发生了什么?为什么12个字节而不是4个字节? 2)我如何获取ca :: vfunc()的地址并在b上调用它,就像我通常用b.ca::vfunc()一样。

2 个答案:

答案 0 :(得分:2)

好的:它正在做它应该做的事情。

但要回答你的问题:

  

1)这里发生了什么?为什么12个字节而不是4个?

为什么不呢。
标准没有规定尺寸 我不确定你为什么期望一个正常的指针是4。

如果问题是“为什么方法指针大于普通指针?”

因为实现需要额外的空间来保存有关呼叫的信息。

  

2)我怎样才能获取ca :: vfunc()的地址并在b上调用它,就像我通常用b.ca::vfunc()那样。

你不能。

答案 1 :(得分:2)

长读,但this article会回答。