是否有一种标准的方法来摆脱读取循环中的开关/大小写块?
即
enum msg_type
{
message_type_1,
//msg types
}
struct header
{
msg_type _msg_type;
uint64_t _length;
}
struct message1
{
header _header;
//fields
}
struct message2
{
header _header;
//fields
}
//socket read loop
void read(//blah)
{
//suppose we have full message here
char* buffer; //the buffer that holds data
header* h = (header*)buffer;
msg_type type = h->_msg_type;
switch(type)
{
case msg_type_1:
message1* msg1 = (message1*)buffer;
//Call handler function for this type
//rest
}
}
这意味着我必须从处理程序容器基类继承,其格式为:
class handler_container_base
{
public:
virtual void handle(message1* msg){}
virtual void handle(message2* msg){}
//etc
}
并将该类型的对象传递给消息循环可以看到的位置,并要求他回拨这些对象。
一个问题是,即使我想实现并只为一个类型注册一个处理程序,我必须从该类继承。 另一个是这看起来很难看。
我想知道是否存在处理此问题的现有库(应该是免费的)。或者没有更好的方法来做这个而不是像这样吗?
答案 0 :(得分:1)
避免继承的其他方法是:
对于一组封闭的类型:
使用变体:
variant<message1_t, message2_t> my_message;
有了访客,你可以做其余的事情。我推荐使用boost.variant。
对于一组开放的类型,您还可以使用boost :: any,并在运行时复制消息。但是,在某些时候,您将不得不回退到原始类型。
另一个解决方案是Poco.DynamicAny,它将尝试转换为分配中左侧的类型,类似于动态语言。但是您需要自己为您的类型注册转换器。