class foo{
public:
int n;
private:
virtual void sayHi(){
cout<<"Hi there!";
}
};
如何获取sayHi()的地址?
main(){
foo f;
typedef void(*fptr)();
fptr func = reinterpret_cast<fptr>((&f)[0]);
(*func)();
}
上面的代码不起作用。
我知道“f”对象的前8个字节是指向虚拟表的指针,其中包含指向函数的指针,我使用的是64位机器。我基本上试图通过它的指针调用sayHi()而不是直接从f调用它,因为sayHi()无论如何都是私有的!我该怎么做?我分配它吗?
答案 0 :(得分:2)
你不能简单地拥有一个指向非静态成员函数的指针,并在没有对象的情况下调用它。解释问题最直接的方法是使用pointer-to-member,如下所示:
auto fptr = &foo::sayHi;
foo f;
(f.*fptr)();
现在,您说要在不必通过f
的情况下调用它。目前尚不清楚这意味着什么。使用lambda可能足以创建一个可以按你想要的方式运行的可调用
auto func = [] { return foo{}.sayHi(); };
func(); // call
或使用特定对象并通过引用(显示)或按值
捕获它foo f;
auto func = [&f] { return f.sayHi(); };
func();
答案 1 :(得分:1)
sayHi()
是类的非静态方法。您需要使用指向方法的指针而不是原始指针(方法指针的实现是特定于编译器的,因此假设指针到方法的内部布局不可移植)
另外,sayHi()
私有到foo
,因此main()
无法直接访问它。你需要:
将sayHi()
声明为 public :
class foo
{
int n;
public:
virtual void sayHi(){
cout << "Hi there!";
}
};
int main()
{
typedef void (foo::*fptr)();
fptr func = &foo::sayHi;
foo f;
(f.*func)();
return 0;
}
将main()
设为friend
的{{1}}:
foo
答案 2 :(得分:0)
嗯,ISO C ++禁止使用绑定成员函数的地址来形成指向成员函数的指针。但是,如果它有帮助,你可以做这样的事情。您可以查看结果here。
#include <iostream>
using namespace std;
class foo{
int n;
public:
virtual void sayHi(){
cout<<"Hi there!";
}
};
typedef void(*fptr)();
int main() {
auto func = reinterpret_cast<fptr>(&foo::sayHi);
(*func)();
return 0;
}