我想在c ++中实现一个具有回调的类.
所以我想我需要一个有两个参数的方法:
条件是:
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::function与boost::bind,或,如果你的编译器支持TR1/C++ 0x中使用std::tr1::function和std::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.
一个技巧是使用接口,这样你就不需要专门知道你的'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)