gpt4 book ai didi

c++ - C++中的简单序列化和反序列化

转载 作者:行者123 更新时间:2023-11-28 02:30:44 24 4
gpt4 key购买 nike

我需要一种方法来序列化不同类型的对象(但类型派生自同一类),然后将它们反序列化为包含派生类的基类的指针。例如:

#include<iostream>
#include<fstream>
class One
{
public:
int a;
virtual void Func()
{
}
};

class One1: public One
{
char s[128];
void Func1(int l)
{
std::cout<<l<<'\n';
}
void Func()
{
Func1(156);
}
};

int main()
{
One* x = new One1;
x->Func();
char* y=(char*)x;
delete x;
/*std::ofstream out("test11.txt",std::ofstream::out | std::ofstream::trunc);
out.write(y,sizeof(One1));
out.close();
std::ifstream in("test11.txt",std::ifstream::in);
char* y1=new char[sizeof(One1)];
in.read(y1,sizeof(One1));*/
One* z=(One*)y/*1*/;
z->Func();
return 0;
}

这段代码输出

156
156

但是当我取消注释时(当我尝试将对象的 char 表示写入文件并从该文件中读取时),程序输出 156 并在尝试执行 z->Func(); 时以段错误结束。我检查了变量 y 的内容与 y1 不同。为什么?
这个问题的原因是什么,我该如何解决(可能通过使用一些特殊的库)?

最佳答案

1。不要通过简单地复制字节来序列化派生类

您不能简单地通过将多态对象转换为字节数组来编写多态对象,然后通过二进制read 加载它们。具有虚函数的类存储指向 vtable 中实现的指针.转储派生类的实例将导致转储存储在 vtable 中的指针,这显然在您再次运行程序后不一定是有效指针。之后访问它很可能会产生段错误。

如果你真的想使用easy方式(直接读写字节),使用POD类。

2。不要访问无效指针

虽然以上是答案中最重要的部分(因为它会完全改变您的程序),但还有其他需要强调的内容。命令:

char* y=(char*)x;

创建一个指向x地址char 指针。它不会复制对象。因此,当您稍后执行以下操作时:

delete x;

指向y 的指针变得无效。当您稍后尝试将其写入文件时:

std::ofstream out("test11.txt",std::ofstream::out | std::ofstream::trunc);
out.write(y,sizeof(One1));

您访问了不属于您的内存。至少不再是了,因为您之前通过调用 delete 明确表示不需要它。

关于c++ - C++中的简单序列化和反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29083491/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com