0

我不确定这在 C++ 中是否可行。我知道您可以将指向函数或静态成员函数的指针作为参数传递。我想要一个特定对象的函数指针,这样当函数执行时,它就在对象上完成。

class MyClass
{
   public:
      MyClass(int id){mId = id;}
      void execute(){cout<<mId<<endl;}
   private:
      int mId;
};


MyClass obj1(1);
MyClass obj2(2);

typedef (Executor)();
Executor ex1 = &obj1::execute();
Executor ex2 = &obj2::execute();

因此,当执行 ex1 时,应打印“1”,如果执行 ex2,则打印“2”。这可能吗?

4

3 回答 3

9

处理这个问题的工具是函数模板bind

auto ex1 = std::bind(&MyClass::execute, obj1);

您可以将绑定存储在function对象中:

std::function<void()> ex1 = std::bind(&MyClass::execute, obj1);

请注意,默认情况下bind将按obj值存储;您可以使用以下方式存储参考ref

std::function<void()> ex1 = std::bind(&MyClass::execute, std::ref(obj1));

一个相关的工具是mem_fn,它包装了一个成员函数指针:

void (MyClass::*ex1)() = &MyClass::execute;  // raw member function pointer
ex1(obj1);

auto ex1 = std::mem_fn(&MyClass::execute);   // mem_fn wrapper
ex1(obj)

但是,因为mem_fn不绑定实例,所以每次调用时都必须提供实例。


为了避免在绑定成员函数时写类名,可以使用宏:

#define BIND_MEM_FN(o,m) \
    std::bind(&std::remove_reference<decltype(o)>::type::m, (o))

宏是必要的,因为您只能从其类型和名称形成成员函数指针,并且不能将名称(非限定 ID)传递给函数。

于 2012-10-22T15:01:08.760 回答
1

这是可能的,但不是你描述的方式。您可以按照上述评论提出的方式进行操作,但更优雅和 C++ 的方式是使用函子。Functor 基本上是一个运算符()重载的对象。在你的情况下,它可能是这样的:

class MyClass
{
   public:
       MyClass(int id){mId = id;}
       void operator()(){cout<<mId<<endl;}
   private:
   int mId;
};

MyClass obj1(1);
MyClass obj2(2);

obj1();
obj2();

这样,您的对象实际上会模仿函数行为。在这里您可以阅读更多信息:http ://en.wikipedia.org/wiki/Function_object#In_C_and_C.2B.2B

于 2012-10-22T15:05:51.147 回答
0

成员函数指针:

typedef void (MyClass::*Executor)();
Executor ex1 = &MyClass::execute;
Executor ex2 = &MyClass::execute;

obj1.*ex1();
obj2.*ex2();

编辑:更正了评论中提到的代码。

我犯了一个错误,因为我确实很少使用(成员)函数指针。但不是因为我使用 std::bind,而是因为我使用多态性 :)

实际上,我不记得上次使用(成员)函数指针是什么时候了,除了与 OS API 接口。成员函数指针优于非成员函数指针,std::bind/std::function 可能优于成员函数指针,但多态性优于上述所有。

于 2012-10-22T15:01:10.913 回答