通过指针调用虚拟函数,无论是否参考 VM 表

发布于 2024-11-23 19:57:07 字数 1172 浏览 2 评论 0原文

我想获取 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 环境,成员函数指针的大小是 3 * 32 位值!当我获取成员函数的地址时,我没有指定对象,但是我的调用调用了 vfunc() 的最后代类的实现。

1)这是怎么回事?为什么是 12 个字节而不是 4 个? 2)如何获取 ca::vfunc() 的地址并在 b 上调用它,就像我通常对 b.ca::vfunc() 所做的那样。

I want to take the address of a member function of a c++ class, store it in a pointer, and call the virtual function later on.

I know some things about it, but do not now how to take the address of a certain implementation of a virtual function that is NOT the implementation of the most descendent class (the actual class of the object).

Here is some sample code:

    #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)();
    }

The output is:

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

I am working with win32-environment, and the size of member function pointers is 3 * 32-bits values! I did not specify an object when I took the address of the member function and yet, my call invokes the most descendant class' implementation of vfunc().

1) What is going on here? Why 12 bytes in stead of 4?
2) How can I take the address of ca::vfunc() and call it on b, like I normaly would do with b.ca::vfunc().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

<逆流佳人身旁 2024-11-30 19:57:10

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

但回答你的问题:

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

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

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

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

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

你不能。

Ok: Its doing exactly what it it is supposed to do.

But to answer you questions:

1) What is going on here? Why 12 bytes in stead of 4?

Why not.
The standard does not specify a size.
I am not sure why you expect a normal pointer to be 4.

If the question is "why is a method pointer larger than a normal pointer?"

Because the implementation needs the extra space to hold information about the call.

2) How can I take the address of ca::vfunc() and call it on b, like I normaly would do with b.ca::vfunc().

You cant.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文