Mar*_*rth 6 c++ coding-style callback
我有一个用C++编写的自定义Menu类.为了将代码分成易于阅读的函数,我正在使用Callbacks.
由于我不想将Singletons用作菜单的主机,因此我提供了另一个参数(目标),它将作为第一个参数提供给回调(缺少"this"引用的某种解决方法).
注册签名
AddItem(string s, void(*callback)(void*,MenuItem*), void* target = NULL)
Run Code Online (Sandbox Code Playgroud)
注册示例
menu->AddItem(TRANSLATE, "translate", &MyApp::OnModeSelected);
Run Code Online (Sandbox Code Playgroud)
处理程序的示例
/* static */
void MyApp::OnModeSelected(void* that, MenuItem* item) {
MyApp *self = (MyApp*)that;
self->activeMode = item->text;
}
Run Code Online (Sandbox Code Playgroud)
这种方法有什么可以考虑的吗?还有更好的吗?
Boj*_*nik 10
您的方法要求回调函数要么是自由函数,要么是类的静态成员.它不允许客户端使用成员函数作为回调.对此的一个解决方案是使用boost :: function作为回调的类型:
typedef boost::function<void (MenuItem*)> callback_type;
AddItem(const std::string& s, const callback_type& callback = callback_type());
Run Code Online (Sandbox Code Playgroud)
然后客户端可以使用boost :: bind或boost :: lambda来传递回调:
menu->AddItem("Open", boost::bind(&MyClass::Open, this));
Run Code Online (Sandbox Code Playgroud)
另一个选择是使用boost :: signals,它允许多个回调注册同一个事件.
我喜欢你的方法.一种替代方法是声明一个接口,这在某种意义上是回调的"OO等价物":
class IMenuEntry {
public:
virtual void OnMenuEntrySelected(MenuItem* item) = 0;
};
Run Code Online (Sandbox Code Playgroud)
注册签名将成为
AddItem(string s, IMenuEntry * entry);
Run Code Online (Sandbox Code Playgroud)
并且方法实现
class MyApp : public IMenuEntry {
public:
virtual void OnMenuEntrySelected(MenuItem* item){
activeMode = item->text;
}
}
Run Code Online (Sandbox Code Playgroud)
接口方法将允许您避免丢失this指针的"void*workaround" .
| 归档时间: |
|
| 查看次数: |
2271 次 |
| 最近记录: |