如何在C ++中实现回调? [英] How do I implement a callback in C++?
问题描述
我想在c ++中实现一个有回调的类。
所以我想我需要一个有两个参数的方法:
- 目标对象。 (让我们说
* myObj) - 指向目标对象
的成员函数的指针。 (所以我可以做
* myObj-> memberFunc();)
条件是:
-
myObj可以来自任何类别。
-
gonna是回调函数是非静态的。
我一直在阅读这篇文章,但看起来我需要知道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){//这里有东西。这将是回调函数};
};
int main(){
Target myTarget;
MyClassWithCallback myCaller;
myCaller.setCallback((void *)& myTarget,& doSomething);
}
我感谢您的帮助。
谢谢。
UPDATE
大多数人说观察和授权,我正在寻找,我是一个Objective-C / Cocoa头脑的家伙。
我当前的实现是使用带有虚函数的接口。只是我认为只是传递对象和一个成员函数指针(如boost!)而不是定义一个接口是更聪明。但是似乎大家都同意接口是最简单的方法吗? Boost似乎是一个好主意(假设已安装)
最好的解决方案,使用 boost :: function
与 boost :: bind
,或者如果你的编译器支持tr1 / c ++ 0x使用 std :: tr1 :: function
和 std :: tr1 :: bind
。
变得很简单:
boost :: function< void()>回电话;
Target myTarget;
callback = boost :: bind(& Target :: doSomething,& myTarget);
callback(); //调用函数
您的set回调函数成为:
class MyClassWithCallback {
public:
void setCallback(boost :: function< void()> const& cb)
{
callback_ = cb;
}
void Call_it(){callback_(); }
private:
boost :: function< void()>回电话_;
};
否则你需要实现一些抽象类
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>回电话_;
};
当然如果你想调用的函数不改变你可能只是实现一些接口,使用此调用从一些抽象类派生Target。
I want to implement a class in c++ that has a callback.
So I think I need a method that has 2 arguments:
- the target object. (let's say *myObj)
- the pointer to a member function of the target object. (so i can do *myObj->memberFunc(); )
The conditions are:
myObj can be from any class.
the member function that is gonna be the callback function is non-static.
I've been reading about this but it seems like I need to know the class of myObj before hand. But I am not sure how to do it. How can I handle this? Is this possible in C++?
This is something I have in mind but is surely incorrect.
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);
}
I appreciate any help.
Thank you.
UPDATE Most of you said Observing and Delegation, well that's i exactly what i am looking for, I am kind of a Objective-C/Cocoa minded guy. My current implementation is using interfaces with virtual functions. Is just I thought it would be "smarter" to just pass the object and a member function pointer (like boost!) instead of defining an Interface. But It seems that everybody agrees that Interfaces are the easiest way right? Boost seems to be a good idea, (assuming is installed)
The best solution, use boost::function
with boost::bind
, or if your compiler supports tr1/c++0x use std::tr1::function
and std::tr1::bind
.
So it becomes as simple as:
boost::function<void()> callback;
Target myTarget;
callback=boost::bind(&Target::doSomething,&myTarget);
callback(); // calls the function
And your set callback becomes:
class MyClassWithCallback{
public:
void setCallback(boost::function<void()> const &cb)
{
callback_ = cb;
}
void call_it() { callback_(); }
private:
boost::function<void()> callback_;
};
Otherwise you need to implement some abstract class
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)
{}
};
And then use:
myCaller.setCallback(new TargetCallback(&Target::doSomething,&myTarget));
When your class get modified into:
class MyClassWithCallback{
public:
void setCallback(callback *cb)
{
callback_.reset(cb);
}
void call_it() { callback_->call(); }
private:
std::auto_ptr<callback> callback_;
};
And of course if the function you want to call does not change you may just implement some interface, i.e. derive Target from some abstract class with this call.
这篇关于如何在C ++中实现回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!