【问题标题】:Passing object's method pointer to function that accept [static method pointer / global function ] pointer将对象的方法指针传递给接受[静态方法指针/全局函数]指针的函数
【发布时间】:2013-12-13 10:54:08
【问题描述】:

我有方法

typedef void
(* JSErrorReporter)(JSContext *cx, const char *message, JSErrorReport *report);

JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);

我想传递对象的方法而不是静态方法

JS_SetErrorReporter(cx,this->Reporter);//Failed ! 

其中 Reporter 是对象的方法(不是静态的)

JS_SetErrorReporter(cx,Reporter); //Passed 

其中 Reporter 是静态方法,声明为

static void SomeClass::reportError(JSContext *cx, const char *message, JSErrorReport *report) 

【问题讨论】:

  • 使用&SomeClass::reportError 那么,this->Reporter 是完全错误的语法(即使对于成员函数指针)。静态方法无论如何都不知道this
  • 你可以做的是提供一个静态方法,它以某种方式从上下文中获取this 指针。我不知道JSContext 是否提供了一些void* userData; 成员,可以用于此。

标签: c++ pointers methods casting


【解决方案1】:

你想使用一个成员函数指针,你必须得到正确的语法,(不是微不足道的) 对于一个无聊的函数,获取并返回一个 int,那就是:

声明一个变量(也适用于参数):

int (SomeClass::*my_memfunc_ptr)(int);

分配一个变量:

 my_memfunc_ptr = &SomeClass::some_member_func;

调用:

  SomeClass *x = new SomeClass;
  int n = (x->*my_memfunc_ptr)(6);

我把这个适应你的非 int 用途留给你。

【讨论】:

    【解决方案2】:

    你不能直接做。因为要调用一些非静态函数,你必须有 this 指针,但你不要将它传递给 JS_SetErrorReporter 函数。

    两种可能的解决方案:

    1. 更改JSErrorReporter 签名以接受void * 类型的+1 参数并在那里传递this 指针。

    2. 创建一个包装函数作为一个全局函数,它也知道需要this指针。

    【讨论】:

      【解决方案3】:

      避免静态函数很容易使用 __closure 函数指针来代替:

      //---------------------------------------------------------------------------
      class C2
          {
          public:
          void callback1() {}                     // your member function to pass to ...
          };
      
      class C1                                    // some class with member function pointer usage
          {
          public:
          void (__closure *callback1)();          // member function pointer
          C1() { callback1=NULL; }                // constructor
          void do_something()                     // some function with use of callback1
              {
              if (callback1) callback1();
              }
          };
      
      void some_function(void (__closure *f)())   // some function with member function parameter usage
          {
          if (f) f();
          }
      
      void main()
          {
          C1 c1;
          C2 c2;
          c1.callback1=c2.callback1;
          c1.do_something();
          some_function(c1.callback1);
          some_function(c2.callback1);
          }
      //---------------------------------------------------------------------------
      

      [编辑 1]

      • 但正如 RichardPlunkett 概述的 __closure 它仅适用于 borland/embarcadero 编译器
      • 对于 VC/GCC/Intel ... 编译器,您需要一种解决方法
      • 那里有一些。
      • 看起来人们更喜欢名为 boost 库的东西
      • 在这里我找到了一个__closure 模仿的例子http://www.rsdn.ru/forum/cpp/3078740.flat
      • 它是俄文的,但即使对于我们 azbuka 非读者来说,源代码也很清楚......

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-11
      • 1970-01-01
      • 1970-01-01
      • 2013-04-28
      • 2018-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多