【问题标题】:Should I use 'memcpy' on class that contains a virtual method?If not, how to replace it?我应该在包含虚方法的类上使用'memcpy'吗?如果不是,如何替换它?
【发布时间】:2020-03-21 16:13:18
【问题描述】:

这是我的简化代码,

class ParentDict {
public:
    virtual some_func();
    virtual reorganize() = 0;

protected:
    int _ssize;
    int _lsize;
}

class ChildDict : public ParentDict {
public:
    virtual some_func();
    virtual reorganize();  // deserialize _arrays here;

private:
    int _array_num;
    char* _arrays;
}

ChildDict* deserialize(void* pool, uint64_t offset) {
    void *ptr = (void *)((uint64_t)pool + offset);
    ChirdDict dict = *((ChildDict *) ptr);

    // HERE is the problem code
    memcpy((void *)ptr, &dict, sizeof(ptr));

    ((ChildDict *) ptr)->reorganize();
    return (ChildDict *)ptr;
}

这段代码试图从文件中反序列化一些类,它运行良好。但是 CPP-rules-checking-system 一直在抱怨 在包含虚拟方法的类上使用 'memcpy'。

我想知道 memcpy 在这里做了什么。也许在虚拟类上使用 memcpy 并不安全,但为什么代码在这里工作?我可以用更好的解决方案代替它吗?

【问题讨论】:

  • 什么是“CPP-rules-checking-system”?
  • 每当您觉得需要编写 C 风格的演员表时,您应该将其视为您正在做一些很可能导致未定义行为的坏事的标志。不幸的是,“似乎有效”是未定义行为的一种可能性,直到您做出一个看似无关紧要的非常轻微的改变,一切都会发生惊人的变化。
  • @foreknownas_463035818 Op 正在创建一个 ChildDict 对象,但它似乎从它复制回第一部分中创建它的内存位置。
  • 抱歉,之前我认为这是一个很好的问题,但是如果该工具是由您的公司构建的,那么您的同事应该能够告诉您为什么拒绝使用虚拟方法复制一个类,尽管有您的代码的其他问题;)
  • 我发现 'memcpy' 存在多个问题。它是否打算根据您正在运行的机器仅复制 sizeof(ptr) 4 或 8 个字节?它是否打算只做一个浅拷贝?

标签: c++ serialization deserialization memcpy


【解决方案1】:

要实际给出答案:要避免 memcopy,您有两个主要选择:

  1. 创建“手动”形成或解释字节数组的自定义序列化和反序列化函数。或者,如果数据大小无关紧要,将数据转换为字符串,变量之间有一些分隔符。

  2. 将所有需要序列化的成员放在一个没有虚函数的简单结构中,并使这样的结构成为类的成员。

【讨论】:

    猜你喜欢
    • 2012-05-25
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 2016-02-08
    相关资源
    最近更新 更多