如何在C++中实现回调?

nac*_*o4d 13 c++ callback

我想在c ++中实现一个具有回调的类.

所以我想我需要一个有两个参数的方法:

  • 目标对象.(让我们说*myObj)
  • 指向目标对象的成员函数的指针.(所以我可以做*myObj-> memberFunc();)

条件是:

  • myObj可以来自任何一个类.

  • 将成为回调函数的成员函数是非静态的.

我一直在读这个,但看起来我需要事先了解myObj的类.但我不知道该怎么做.我怎么处理这个?这在C++中是否可行?

这是我想到的,但肯定是不正确的.

class MyClassWithCallback{
public
    void *targetObj;
    void (*callback)(int number);
    void setCallback(void *myObj, void(*callbackPtr)(int number)){
        targetObj = myObj;
        callback = callbackPtr;
    };
    void callCallback(int a){
        (myObj)->ptr(a);
    };
};
class Target{
public
    int res;
    void doSomething(int a){//so something here. This is gonna be the callback function};        
};

int main(){
    Target myTarget;
    MyClassWithCallback myCaller;
    myCaller.setCallback((void *)&myTarget, &doSomething);
Run Code Online (Sandbox Code Playgroud)

}

我感谢任何帮助.

谢谢.

更新大多数人说观察和代表,这就是我正在寻找的,我是一个Objective-C/Cocoa头脑的家伙.我目前的实现是使用具有虚函数的接口.我只是认为传递对象和成员函数指针(如boost!)而不是定义接口会"更聪明".但似乎每个人都认为Interfaces是最简单的方法吗?Boost似乎是一个好主意,(假设已安装)

Art*_*yom 16

最好的解决办法,使用boost::functionboost::bind,或,如果你的编译器支持TR1/C++ 0x中使用std::tr1::functionstd::tr1::bind.

所以它变得如此简单:

boost::function<void()> callback;
Target myTarget;
callback=boost::bind(&Target::doSomething,&myTarget);

callback(); // calls the function
Run Code Online (Sandbox Code Playgroud)

你的回调变为:

class MyClassWithCallback{
public:
  void setCallback(boost::function<void()> const &cb)
  {
     callback_ = cb;
  }
  void call_it() { callback_(); }
private:
  boost::function<void()> callback_;
};
Run Code Online (Sandbox Code Playgroud)

否则你需要实现一些抽象类

struct callback { 
 virtual void call() = 0;
 virtual ~callback() {}
};

struct TargetCallback {
 virtual void call() { ((*self).*member)()); }
 void (Target::*member)();
 Target *self;
 TargetCallback(void (Target::*m)(),Target *p) : 
       member(m),
       self(p)
 {}
};
Run Code Online (Sandbox Code Playgroud)

然后使用:

myCaller.setCallback(new TargetCallback(&Target::doSomething,&myTarget));
Run Code Online (Sandbox Code Playgroud)

当您的课程被修改为:

class MyClassWithCallback{
public:
  void setCallback(callback *cb)
  {
     callback_.reset(cb);
  }
  void call_it() { callback_->call(); }
private:
  std::auto_ptr<callback> callback_;
};
Run Code Online (Sandbox Code Playgroud)

当然,如果你要调用的函数没有改变,你可能只是实现了一些接口,即通过这个调用从一些抽象类派生Target.


And*_*rsK 8

一个技巧是使用接口,这样你就不需要专门知道你的'MyClassWithCallback'中的类,如果传入的对象实现了接口.

例如(伪代码)

struct myinterface
{
  void doSomething()=0;
};

class Target : public myinterface { ..implement doSomething... };
Run Code Online (Sandbox Code Playgroud)

myinterface *targetObj; 
void setCallback(myinterface *myObj){
    targetObj = myObj;
};
Run Code Online (Sandbox Code Playgroud)

做回调

targetObj->doSomething();
Run Code Online (Sandbox Code Playgroud)

设置:

Target myTarget;
MyClassWithCallback myCaller;
myCaller.setCallback(myTarget);
Run Code Online (Sandbox Code Playgroud)


Gre*_*ton 5

观察者设计模式似乎是你在找什么.