我序列化了一个C ++对象,如何在不知道它是什么类型的情况下为它分配内存?

时间:2010-03-29 13:40:43

标签: c++ class serialization object

我已经序列化了一个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;

这会导致程序关闭。

提前谢谢。

5 个答案:

答案 0 :(得分:11)

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

我不确定你有没有。如果你写了这样的话:

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

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

例如,如果您正在编写CFoo对象,请首先传输值“1”。如果您正在编写CBar,请传输值“2。

然后,当回读档案时,如果你看到“1”你知道你必须“新”CFoo,如果你读了“2”,你就知道你必须要新建一个CBar。

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

答案 3 :(得分:0)

您需要以下代码

object *o = new objectchild;

使用dynamic_cast

答案 4 :(得分:0)

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