我想在 C++ 中实现一个具有回调的类。
所以我想我需要一个有 2 个参数的方法:
- 目标对象。 (假设 *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);
}
感谢您的帮助。
谢谢。
更新 你们中的大多数人都说观察和委托(delegate),这正是我正在寻找的,我是一个有 Objective-C/Cocoa 思想的人。 我目前的实现是使用带有虚拟功能的接口(interface)。只是我认为只传递对象和成员函数指针(如boost!)而不是定义接口(interface)会“更聪明”。但似乎每个人都同意接口(interface)是最简单的方法,对吧? Boost似乎是个好主意,(假设已安装)
最佳答案
最好的解决方案,使用 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
你设置的回调变成:
class MyClassWithCallback{
public:
void setCallback(boost::function<void()> const &cb)
{
callback_ = cb;
}
void call_it() { callback_(); }
private:
boost::function<void()> callback_;
};
否则你需要实现一些抽象类
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)
{}
};
然后使用:
myCaller.setCallback(new TargetCallback(&Target::doSomething,&myTarget));
当你的类被修改为:
class MyClassWithCallback{
public:
void setCallback(callback *cb)
{
callback_.reset(cb);
}
void call_it() { callback_->call(); }
private:
std::auto_ptr<callback> callback_;
};
当然,如果您要调用的函数没有改变,您可以只实现一些接口(interface),即通过此调用从某个抽象类派生 Target。
关于c++ - 如何在 C++ 中实现回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3381829/