通过指针调用虚拟函数,无论是否参考 VM 表
我想获取 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的:它正在做它应该做的事情。
但回答你的问题:
为什么不呢。
标准没有规定尺寸。
我不知道为什么你期望普通指针是 4。
如果问题是“为什么方法指针比普通指针大?”
因为实现需要额外的空间来保存有关调用的信息。
你不能。
Ok: Its doing exactly what it it is supposed to do.
But to answer you questions:
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.
You cant.