2010-06-18 144 views
26

我正在尝试打印虚拟成员函数的地址。 如果我知道哪些类实现了功能我可以写:虚拟成员函数的打印地址

print("address: %p", &A::func); 

但我想要做这样的事情:

A *b = new B(); 

printf("address: %p", &b->func); 
printf("address: %p", &b->A::func); 

然而,这并不编译。是否有可能做这样的事情,也许在运行时查看vtable中的地址?

回答

1

对我来说没有太多意义。如果你有一个正常的功能:

void f(int n) { 
} 

那么你可以采取其地址:

f 

,但你不能把一个函数调用,地址是你似乎什么想做的事情。

+0

@GMan这就是我想我说的。无论如何,我不认为这是可能的。 – 2010-06-18 08:44:19

1

从我在标准中可以看出,唯一一次获得动态绑定的是虚函数,请致电。一旦你调用了一个函数,你正在执行函数中的语句(即,你不能“中途停止”进入呼叫并获取地址。)

我认为这是不可能的。

+0

我想这是不可能的,但知道实现它应该有可能在运行时检查对象的虚拟表。 – 2010-06-18 13:03:17

6

指向成员函数的指针并不总是简单的内存地址。请参阅this article中的表格,其中显示了不同编译器上成员函数指针的大小 - 有些最多为20个字节。

由于文章概述了一个成员函数指针实际上是一个实现定义的数据blob,以帮助通过指针解析调用。你可以存储和调用它们,但是如果你想打印它们,你打印什么?最好把它当作一个字节序列,并通过sizeof得到它的长度。

+4

然而,问题仍然存在:你如何确定通过虚拟调用调用的函数? – 2010-06-18 13:01:27

+1

这不是问题的一部分吗?但我会回答'通过调用':) – AshleysBrain 2010-06-18 14:24:32

11

目前在C++中没有这样做的标准方式,尽管信息必须在某处可用。否则,程序如何调用该函数?然而,GCC提供了一个扩展,使我们能够检索虚函数的地址:

void (A::*mfp)() = &A::func; 
printf("address: %p", (void*)(b->*mfp)); 

...假设成员函数原型void func()。 当您想要缓存虚拟函数的地址或在生成的代码中使用它时,这可能非常有用。除非你指定-Wno-pmf-conversions,否则GCC会警告你这个构造。它不太可能与其他编译器一起工作。