多个回调处理程序
multiple callback handlers
考虑片段:
# include <iostream>
# include <boost/scoped_ptr.hpp>
# include <boost/shared_ptr.hpp>
# include <boost/function.hpp>
# include <boost/array.hpp>
# include <boost/asio.hpp>
# include <boost/thread.hpp>
# include <boost/thread/locks.hpp>
# include <boost/bind.hpp>
# include <boost/noncopyable.hpp>
# include <boost/variant.hpp>
class DataLink {};
class Metadata {};
class Image {};
typedef boost::function<void( DataLink const&, Metadata const& , Image const& )> Handler ;
typedef boost::function<void( Metadata const& , Image const& )> Handler2 ;
typedef boost::function<void( Image const& )> Handler3 ;
typedef boost::variant<DataLink, Metadata, Image> Variant;
enum callbackHandler { link_enum, meta_enum, image_enum };
class Worker {
Handler callBack ;
//Handler2 callBack2 ;
//Handler3 callBack3 ;
DataLink dlink;
Metadata meta ;
Image img ;
callbackHandler handlerEnum ;
public :
Worker ( const Handler& handler )
: callBack ( handler )
{}
//Worker ( const Handler2& handler )
//: callBack2 ( handler )
// {}
//Worker ( const Handler3& handler )
//: callBack3 ( handler )
// {}
void Image ( ) {
// update the img object
// invoke call back
handlerEnum = image_enum ;
//const std::type_info& xxx = callBack.target_type();
//std::cout << xxx.raw_name() << std::endl;
callBack ( dlink, meta, img ) ;
}
void Metadata ( ) {
// update the meta object
// invoke call back
handlerEnum = meta_enum ;
callBack ( dlink, meta, img ) ;
}
void Dlink ( ) {
// update the link object
// invoke call back
handlerEnum = link_enum ;
callBack ( dlink, meta, img ) ;
}
callbackHandler getHandlerType() { return handlerEnum ; }
};
class Foo {
Worker *ptrWorker ;
public :
Foo ()
: ptrWorker( 0 )
{}
void callback ( DataLink const& d, Metadata const& m , Image const& i ) {
callbackHandler tt = ptrWorker->getHandlerType();
if ( tt == image_enum ) {
std::cout << "Image object " << std::endl;
}
if ( tt == meta_enum ) {
std::cout << "Meta object " << std::endl;
}
if ( tt == link_enum ) {
std::cout << "Link object " << std::endl;
}
}
bool start () {
ptrWorker = new ( std::nothrow ) Worker ( boost::bind ( &Foo::callback, this, _1, _2, _3 ) );
if ( !ptrWorker ) {
return - 1 ;
}
}
void testWorker() {
ptrWorker->Image() ;
ptrWorker->Metadata() ;
ptrWorker->Dlink() ;
}
};
int main() {
Foo f;
f.start() ;
f.testWorker() ;
std::cin.get() ;
}
注释掉的构造函数允许我添加对Handler2和Handler3的支持,但是有没有办法确定传递给Worker类构造函数的处理程序?目前,成员函数Metadata、Image和Dlink使用"callBack"对象。如果用户处理程序传入了另一个处理程序,比如Handler2,我需要进行区分
事实上,我需要使用枚举来实现,这实际上是我自己的类型系统(按照判别联合的形式,也就是变体),这也是一个肯定的迹象,表明设计需要重新思考,所以在这种情况下,我愿意重新设计。必须在类中定义N-1个伪处理程序(即,在任何时候都只使用一个处理程序,而其他处理程序则什么都不做),这让对象模型感到困惑和低内聚性,但谁知道呢。
您可以使用从虚拟基类派生的函子来实现这一点
struct CallbackBase
{
// Dummy virtual functions that does nothing
virtual operator()(DataLink const &, Metadata const &, Image const &) {}
virtual operator()(Metadata const &, Image const &) {}
virtual operator()(Image const &) {}
};
class Worker
{
CallbackBase &callback_;
public:
Worker(const CallbackBase &callback)
: callback_(callback)
{ }
void Image()
{
// Do something...
callback_(img);
}
void Metadata()
{
// Do something...
callback_(meta, img);
}
void Dlink()
{
// Do something...
callback_(dlink, meta, img);
}
};
struct MyCallback : public CallbackBase
{
virtual operator()(Image const &)
{
// Do something useful here
}
};
MyCallback my_callback;
Worker my_worker(my_callback);
由于基本回调类中存在重载,Worker
类可以在正确的位置调用其中的任何一个,而您只能在派生回调类中实现实际需要的回调。
相关文章:
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 为什么我的 IExtractIcon 处理程序没有被调用?
- 在遍历处理程序的向量时注册和注销处理程序
- 有可能在信号处理程序中设置promise吗
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 在C++程序中使用的迭代器中未处理的异常
- 有关图像处理应用程序的硬件和软件安全性的建议
- 通过安装信号处理程序关闭多线程应用程序
- QDateTime::toString() 在退出处理程序中使用时失败
- 如何在 WindowProc 处理程序中区分箭头键和数字键盘?
- async_write完成处理程序最早何时完成?
- C++事件系统 - 多态事件和事件处理程序
- 使用信号处理程序处理从 FIFO 接收的数据
- 使用独立的 c++ 程序处理用 C 编写的字符设备驱动程序
- C 程序处理两个文件,而不是一个文件
- 是什么让这个程序处理缓慢?(C++)
- QT 中的应用程序>处理消息?
- MongoDB C++驱动程序处理副本集连接故障
- 使用 OpenCV 程序处理多页 PDF