开发者

calling virtual functions through pointers with and without consulting the VM-table

开发者 https://www.devze.com 2023-03-19 15:26 出处:网络
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 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,开发者_StackOverflow 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().


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消