Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何拆卸这种开关盒?_C++ - Fatal编程技术网

C++ 如何拆卸这种开关盒?

C++ 如何拆卸这种开关盒?,c++,C++,我想通用化大量内存,可能是从二进制文件加载的,并且消息id是已知的,我需要为每个内存块创建新实例。最好的方法是什么 目前的情况是,我需要将每个新添加的消息类型添加到下面的开关案例中 struct Message1; struct Message2; void UnSerialize(int messageId, void* data) { switch (messageId) { case MESSAGE1: Message1* m1 = new Message

我想通用化大量内存,可能是从二进制文件加载的,并且消息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;
    }
}

有一些方法可以表示对列表(类型,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;
    }
}
模板
作废取消序列化(作废*数据){
静态断言(std::是可复制的::值,
“消息类不可三重复制”);
T消息;
memcpy(&message,data,sizeof(T));
message.dump();
}
void取消序列化(int messageId,void*数据){
开关(messageId){
案例信息1:
取消序列化(数据);
打破
案例信息2:
取消序列化(数据);
打破
违约:

std::cout我不确定您想做什么,但是如果您只想从
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();
}

假设的
UnSerialize
相当于
void UnSerialize(MessageTypeList tl,int messageId,void*data){}
。除了内存泄漏之外,它没有任何副作用。因此,原始的
void UnSerialize(int messageId,void*data)也是如此
。所有分配的内存会发生什么情况?在switch语句中创建消息后,消息会发生什么情况?如果只是执行memcpy,为什么消息类型很重要?(类的memcpy可能非常糟糕)。您的代码无效,
memcpy
正在复制指针的大小。
new Message1;
也不适用于不完整的类型。您使用动态分配显然是没有原因的。它将有助于显示
Message1
等的示例。在
foreach
中,您是否正在寻找一种方法来迭代所有类的列表在C++中,你不能用编程方式获得这种信息,你需要自己跟踪它。在非序列化函数中,单行代码是什么?<代码>((t*)数据)->哑()
@Quest,这应该适用于大多数应用程序,但必须注意确保每个
T
数据都正确对齐。我看不出这会如何解决问题,因为
非串行化
实际上接收到一个任意映射到某些类型的整数和一个指向字节数组的指针给定函数名和整数参数的需要,字节数可能无法正确设置vtable指针,因此虚拟函数调用将不起作用。
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();
}