gpt4 book ai didi

C++ 二进制文件读取

转载 作者:太空宇宙 更新时间:2023-11-04 14:13:46 24 4
gpt4 key购买 nike

我试图将包含对象 vector 的对象保存在二进制文件中。

下面是一些来自文件的加载代码:

template <class T> void read(T* obj,std::ifstream * file) {
file->read((char*)(obj),sizeof(*obj));
file->seekg(int(file->tellg())+sizeof(*obj));
}

void read_db(DB* obj,std::ifstream * file) {
read<DB>(obj,file);
for(int index = 0;index < obj->Arrays.size();index++) {
std::cin.get(); //debugging
obj->Arrays[0].Name = "hi"; //debugging
std::cin.get(); //debugging
std::cout << obj->Arrays[0].Name;
read<DB_ARRAY>(&obj->Arrays[index],file);
for(int row_index = 0;row_index < obj->Arrays[index].Rows.size();row_index++) {
read<DB_ROW>(&obj->Arrays[index].Rows[row_index],file);
for(int int_index = 0;int_index < obj->Arrays[index].Rows[row_index].i_Values.size();int_index++) {
read<DB_VALUE<int>>(&obj->Arrays[index].Rows[row_index].i_Values[int_index],file);
}
}
}
}

这是 DB/DB_ARRAY 类

class DB {
public:
std::string Name;
std::vector<DB_ARRAY> Arrays;
DB_ARRAY * operator[](std::string);
DB_ARRAY * Create(std::string);
};
class DB_ARRAY {
public:
DB* Parent;
std::string Name;
std::vector<DB_ROW> Rows;
DB_ROW * operator[](int);
DB_ROW * Create();
DB_ARRAY(DB*,std::string);
DB_ARRAY();
};

所以现在 read_db 函数的第一个参数将具有正确的值,并且对象上的 vector 数组具有正确的大小,但是如果我从 obj->Arrays 索引任何对象的任何值,它将引发访问冲突异常(exception)。

std::cout << obj->Arrays[0].Name; // error
std::cout << &obj->Arrays[0]; // no error

后者总是打印相同的地址,所以当我保存一个转换为 char* 的对象时,它是否也保存了它的地址?

最佳答案

正如许多评论者所指出的,您不能简单地通过保存/恢复对象的内存来序列化(非 POD)对象。

实现序列化的通常方法是在类上实现序列化接口(interface)。像这样:

struct ISerializable {
virtual std::ostream& save(std::ostream& os) const = 0;
virtual std::istream& load(std::istream& is) = 0;
};

然后您在可序列化类中实现此接口(interface),对引用其他可序列化类的任何成员递归调用saveload,并写出任何 POD 成员。例如:

class DB_ARRAY : public ISerializable {
public:
DB* Parent;
std::string Name;
std::vector<DB_ROW> Rows;
DB_ROW * operator[](int);
DB_ROW * Create();
DB_ARRAY(DB*,std::string);
DB_ARRAY();

virtual std::ostream& save(std::ostream& os) const
{
// serialize out members
return os;
}

virtual std::istream& load(std::istream& is)
{
// unserialize members
return os;
}
};

正如 count0 指出的那样,boost::serialization也是一个很好的起点。

关于C++ 二进制文件读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12842308/

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