如何拆除这种开关箱
How to remove this kind of switch case?
我想通用化大量内存,这些内存可能是从二进制文件加载的,并且消息id是已知的,我需要为每个内存块创建新的实例。最好的方法是什么?
目前的情况是,我需要将每个新添加的消息类型添加到以下交换机案例中。
struct Message1;
struct Message2;
void UnSerialize(int messageId, void* data) {
switch (messageId) {
case MESSAGE1:
Message1* m1 = new Message1;
std::memcpy(m1, data, sizeof(Message1));
m1.dump();
delete m1;
break;
case MESSAGE2:
Message2* m2 = new Message2;
std::memcpy(m2, data, sizeof(MESSAGE2));
m2.dump();
delete m2;
break;
default:
std::cout << "Unknown Message Type.";
break;
}
}
我能用C++写下面这样的东西吗?没有C++11和boost可能吗?
MessageTypeList tl;
tl.append(Message1);
tl.append(Message2);
void UnSerialize(MessageTypeList tl, int messageId, void* data) {
{
foreach( type t : tl ) {
if (t::id == MessageId) {
t instance = new t;
memcpy(t, data, sizeof(t));
instance.dump();
delete instance;
}
}
}
我不确定您想做什么,但如果您只想从Message1
或Message2
结构调用Dump
函数,可以执行以下操作:
struct BaseMessge
{
virtual void Dump() = 0;
};
struct Message1 : public BaseMessage
{
void Dump()
{
//Your code
}
};
struct Message2 : public BaseMessage
{
void Dump()
{
//Your code
}
};
void UnSerialize(BaseMessage *Message)
{
Message->Dump();
}
有一些方法可以表达对(type,id)的列表,并为每个类型或id实现您想要的任何行为。然而,我认为开关仍然是一个非常好的方法-在任何方法中,您都必须尽快列出所有类型-但让每个案例中的代码成为一个模板函数。
template <class T>
void UnSerialize(void* data) {
static_assert(std::is_trivially_copyable<T>::value,
"Message class is not trivally copyable");
T message;
memcpy(&message, data, sizeof(T));
message.dump();
}
void UnSerialize(int messageId, void* data) {
switch (messageId) {
case MESSAGE1:
UnSerialize<Message1>(data);
break;
case MESSAGE2:
UnSerialize<Message2>(data);
break;
default:
std::cout << "Unknown Message Type.";
break;
}
}
注意,我已经为每个案例中的代码建议了一个不同的实现:
- 没有动态分配,消息是在函数的本地变量中分配的
- 添加了一个静态断言,即
memcpy
将按预期工作
另一种完全避免switch
的方法是使用虚拟方法构建一个ID和助手类实例对的数组。每个实例都来自一个派生的模板类,该类使用本例中的代码来实现该虚拟方法。然后,您只需要静态地构建该数组(我建议使用std::unique_ptr
来保存指向helper类的指针)。
请注意,编写该数组与编写switch
非常相似,只会使代码更难阅读。
相关文章:
- 既然存在危险,为什么项目要使用-I include开关
- 函数何时会在c++中包含stack_Unwind_Resume调用
- Python中的for循环与C++有何不同
- 为什么这个音频包络不能通过开关的情况?
- 有人知道为什么在开关中使用stoi函数会返回恒定的错误吗
- C 和 C++ 中开关语句的案例标签的常量值,但显示不同的行为
- 在 c++ 中在开关情况下使用和不使用"break"时的不同输出
- 为什么我的开关/机箱在使用枚举时默认?
- 在C++中释放内存期间,迭代器与指针有何不同
- QT编程中的非初始化开关箱错误
- C 17元组拆箱
- 如何拆除这种开关箱
- 开关箱多工况
- 开关箱中的局部作用域
- int开关箱的问题
- 开关箱运行时类型检查
- 开关箱中"case"常量是否有变量类型?
- 开关箱如何处理"case"中的常量值?
- 开关箱尺寸动态变化
- 多开关箱设计模式