假设我有一些这样的代码:
class Visitor {
public:
Visitor(callBackFunction) {}
void visit() {
//do something useful
invokeCallback();
}
}
class ClassThatCanBeVisited {
Visitor &visitor;
public:
ClassThatCanBeVisited(Visitor &_visitor) : visitor(_visitor){}
void someUsefulMethod() {
int data= 42;
visitor.visit(data);
}
};
void callBackFunction() {
//do something useful in the context of the Main file
}
int main() {
Visitor visitor;
ClassThatCanBeVisited foo(visitor);
foo.someUsefulMethod();
}
我需要创建一个简单的回调,只要调用Visitor :: visit(),就会调用它。我知道我可能应该将回调代码放在我的访问者中,但是它位于不同的上下文中,所以我想将callBackFunction()传递给Visitor,这样他就可以调用我的回调函数。
我在网上查找了一些内容并看到了boost :: function,但是c ++已经有了基本的函子。
为了更清晰的代码,我应该使用哪一个?回调将是一个简单的void()函数,但它可能会增长,你永远不会知道未来:)
建议的方法是什么?
答案 0 :(得分:7)
是的boost :: function会做得很好。这是一个非常常见的用法。您需要使用boost :: bind将实例绑定到成员函数。
func = boost::bind( &MyClass::CallbackFunc, this);
你将如何在课堂上做到这一点。
确保“this”不会消失,或者你的升压功能会在某处的某个升级标题中间崩溃。
答案 1 :(得分:4)
如果您不想使用boost :: function。
,可以使用回调接口及其层次结构class VisitorCallback
{
public:
virtual void handle( const Visitor& ) = 0;
};
如果你有或者可以使用boost :: function - 使用它,那么它是摆脱所有这些回调类的好方法。
修改:
强>
@edisongustavo:
boost :: function和boost :: bind不会让你的代码更具可读性。但是它会让你有机会传递自由函数(我的意思是类和静态类函数之外的函数)作为回调以及任何类的现有函数。
使用boost函数,您可以传递函数,例如2个参数作为回调,只需要一个参数。
typedef boost::function< void ( int ) > IntExpectingCallback;
void TwoIntFunction( int, int );
{
}
...
IntExpectingCallback callback = boost::bind( TwoIntFunction, 5, _1 );
但是,除非你的所有团队都知道并赞成提升,否则这不会使你的代码更具可读性。
答案 2 :(得分:1)
上面的答案很棒,但我想指出你在问题中提到的内容,这仍然与你在C ++回调对象(在Mykola的答案中)和boost之间的选择有关。
“回调将是一个简单的void()函数,但它可能会增长,你永远不会知道未来:)”
这可能是额外的,不必要的功能的最坏理由 - “以防万一你需要它”。如果你不知道 - 那么做的不是必要的,那么你的猜测很可能是错的,特别是在你需要的时候。
另一方面,如果您确实知道您很可能很快需要功能,那么可能值得添加它。
再次重复Mykola所说的话 - 如果你已经在你的项目中有所提升并且你的团队喜欢它,那么就使用它,否则它可能会有点过分。