【问题标题】:I serialized a C++ object, how to allocate memory for it without knowing what type it is?我序列化了一个 C++ 对象,如何在不知道它是什么类型的情况下为其分配内存?
【发布时间】:2011-02-02 01:18:39
【问题描述】:

我已经序列化了一个 C++ 对象,我希望为它分配空间,虽然我不能使用“new”运算符,因为我不知道对象的类。我尝试使用 malloc(sizeof(object)),虽然尝试将指针类型转换为序列化对象的类型,但程序关闭。对象类的信息存放在哪里?

class object
{
  public:
    virtual void somefunc();
    int someint;
};

class objectchild:public object
{
}

object *o=(object*)malloc(sizeof(objectchild));

cout << int(dynamic_cast<objectchild*>(o)) << endl;

这会导致程序关闭。

提前谢谢你。

【问题讨论】:

  • 为什么不在序列化中包含类型信息?
  • 我不明白你的担心,你知道它的objectchild,但仍然不想使用new,这很奇怪。
  • 我有一个在 char* 变量中序列化的对象,我通过 tcp/ip 协议发送它,但我需要知道另一端是什么对象,但我希望没有每次添加新类时都更改算法...我更愿意在没有任何其他库的情况下这样做。

标签: c++ class serialization object


【解决方案1】:

我已经序列化了一个 C++ 对象

我不确定你有。如果你写过这样的东西:

object *p = new objectchild();
some_file.write((char*)p, sizeof(objectchild));

那么你还没有序列化你的对象。您已经将一些数据写入文件,并且(在大多数实现中)该数据包括指向 vtable 的指针和类型信息。当您“反序列化”数据时,在另一台机器上或在同一程序的另一次运行中,vtable 通常不会位于同一地址,并且指针是无用的。

在 C++ 中序列化对象的唯一方法是以您设计的已知格式编写其数据成员。该已知格式应包含足够的信息来确定对象的类型。有一些框架可以帮助您解决这个问题,但与 Java 不同的是,该语言或标准库中没有内置机制。

【讨论】:

    【解决方案2】:

    您不应该混合使用 C++ 和 C 内存路由。 dynamic_cast 检查对象的实际类型。在您的情况下,您将原始内存投射到 object *

    【讨论】:

      【解决方案3】:

      重写您的代码,以便您可以以某种方式从序列化存档中读取对象的类型。您可以通过字符串或您使用的一些自定义值来执行此操作,但它可能不是通用的。

      例如,如果您正在编写一个 CFoo 对象,则首先流式传输值“1”。如果您正在编写 CBar,请流式传输值 "2 .

      然后,在回读存档时,如果您看到“1”,您就知道您必须“新建”一个 CFoo,如果您看到“2”,您就知道您必须新建一个 CBar。

      或者,您可以使用功能齐全的序列化库(或将其用作灵感)。 参见例如boost::serialization

      【讨论】:

        【解决方案4】:

        你需要以下代码

        object *o = new objectchild;
        

        使用dynamic_cast

        【讨论】:

          【解决方案5】:

          您正在尝试动态转换一个没有任何内容的内存位置。 malloc 为您提供了放置对象的空闲空间,但是在调用 new() 运算符之前,没有对象存在,因此当 dynamic_cast 执行时,它的类型安全检查将失败。您可以尝试使用 static_cast 而不是 dynamic_cast,因为 static 不会进行类型安全检查,但实际上您不应该像这样混合 C 和 C++ 分配/转换样式。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-11-21
            • 2021-10-17
            • 2011-02-10
            • 2021-07-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-02
            相关资源
            最近更新 更多