通过指针访问私有虚拟成员函数

Access a private virtual member-function through pointers

本文关键字:虚拟成员 函数 访问 指针      更新时间:2023-10-16
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(( 无论如何都是私有的!我该怎么做?我分配的对吗??

不能简单地有一个指向非静态成员函数的指针,并在没有对象的情况下调用它。解释问题最直接的方法是使用指向成员的指针,如下所示:

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();
sayHi()

类的非静态方法。 您需要使用指针到方法而不是原始指针(方法指针的实现是特定于编译器的,因此假设指针到方法的内部布局不可移植(。

此外,sayHi()foo私有的,因此main()无法直接访问它。 您需要:

  1. sayHi()声明为公共

    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;
    }
    
  2. main()成为foofriend

    class foo
    {
       int n;
       virtual void sayHi(){
          cout << "Hi there!";
       }
       friend int main();
    };
    int main()
    {
        typedef void (foo::*fptr)();
        fptr func = &foo::sayHi;
        foo f;
        (f.*func)();
        return 0;
    }
    

好吧,ISO C++禁止获取绑定成员函数的地址来形成指向成员函数的指针。但是,如果有帮助,您可以执行此类操作。您可以在此处查看结果。

#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;
}