Cha*_*cui 2 c++ virtual function
我搜索了这篇文章: C++:使用成员函数指针获取函数虚拟'地址'
为了测试虚拟成员函数是否通常位于对象的起始地址,我编写了如下代码:
#include <pwd.h>
#include <string.h>
#include <stdio.h>
class Base
{
public:
int mBase1;
char mBase2;
virtual void foo()
{
fprintf(stderr,"Base foo called\n");
}
};
class Child: public Base
{
public:
int cc;
virtual void foo()
{
fprintf(stderr,"Child foo called");
}
};
int main(int argc, char *argv[])
{
Base bb;
fprintf(stderr,"[mBase1 %p][mBase2 %p] [foo %p]\n",&bb.mBase1,&bb.mBase2,&Base::foo);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在编译时,我收到了一个警告:
test.cpp:30:88: warning ‘%p’ expects argument of type ‘void*’, but argument 5 has type ‘void (Base::*)()’ [-Wformat]
Run Code Online (Sandbox Code Playgroud)
输出是:
[mBase1 0xbfc2ca38][mBase2 0xbfc2ca3c] [foo 0x1]
Run Code Online (Sandbox Code Playgroud)
我认为这是有线的.
是否有任何"漂亮的方法"来获取成员函数(不是静态成员函数地址?).除了以下方法,还有其他优雅方式吗?
typedef void (Base::*Foo)();
Foo f = &Base::foo();
Run Code Online (Sandbox Code Playgroud)为什么没有&Base::foo得到正确的C++成员地址?
为什么&Base :: foo没有获得正确的C++成员地址?
指向成员的指针与指针的类型不同(事实上,它们比类型本身更多的偏移),特别是它们无法转换为void*(它们可以在GCC上,但它可能是编译器扩展).
请参阅C++ 11标准的第8.3.3/3节:
指向成员的指针不应指向**类的静态成员(9.4),具有引用类型的成员或"cv void".[注意:另请参见5.3和5.5."指向成员的指针"类型与"指针"类型不同,也就是说,指向成员的指针仅由指向成员声明符语法的指针声明,而不是由指针声明符语法声明.C++中没有"reference-to-member"类型. - 尾注]
此外,第5.2.10/10段(约reinterpret_cast<>)定义了成员指针的唯一可能转换,如下所示:
如果T1和T2都是函数类型或两种对象类型,则可以将类型为"T1类型X的成员的指针"的prvalue显式转换为不同类型的prvalue"指向类型为T2的Y的成员的指针".空成员指针值(4.11)将转换为目标类型的空成员指针值.除以下情况外,此转换的结果未指定:
- 将"指向成员函数的指针"类型的prvalue转换为指向成员函数类型的不同指针,并返回其原始类型,从而生成指向成员值的原始指针.
- 将"指向类型T1的X的数据成员的指针"的类型的prvalue转换为"类型为T2的Y的数据成员的指针"类型(其中T2的对齐要求不比T1的更严格)并返回到其原始类型产生指向成员值的原始指针.