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

ber*_*jan 5 c++ virtual pointers 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)();
    }
Run Code Online (Sandbox Code Playgroud)

输出是:

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

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

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

Mar*_*ork 2

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

但回答你的问题:

1)这是怎么回事?为什么是 12 个字节而不是 4 个?

为什么不。
该标准没有指定尺寸。
我不知道为什么你期望普通指针是 4。

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

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

2)如何获取 ca::vfunc() 的地址并在 b 上调用它,就像我通常对 b.ca::vfunc() 所做的那样。

你不能。