我有以下类
class WriterCollection
{
std::vector<Writer> arts;
public:
WriterCollection(void);
~WriterCollection(void);
void DisplayMenu();
void AddWriter();
void EditWriter();
void ShowWriterList();
int SearchWriter(std::string name = "");
};
我试图将它保存在二进制文件
所以我有
WriterCollection ac;
ac.AddWriter();
ac.AddWriter();
ac.AddWriter();
结果是它要求我为每个Writer指定一个名称,我也可以为每个Writer添加一个book向量
然后保存:
std::ofstream output_file("db.data", std::ios::binary);
output_file.write((char*)&ac, sizeof(ac));
output_file.close();
当程序启动时,我试着读取它…
std::ifstream in( "db.data", std::ios::in );
if ( !in )
{
std::cerr << "File could not be opened." << std::endl;
}
in.read( reinterpret_cast< char * >( &ac ), sizeof( ac ) );
它正确地说在我的集合中有一个包含3个元素的向量但是它无法告诉我这些元素的数据…
谁能帮我一下?永远不要尝试将c++类存储为二进制转储。
首先,std::vector包含一个指向实际数据的指针和一个大小。你写入文件的只是指针和大小;实际数据不写入。读回数据后,指针指向内存中的某个位置,但该位置没有数据。
但是,即使您的数据都存储在一个地方,编写二进制转储仍然是一个坏主意。如果类具有虚成员函数,则内存中的对象包含指向相应虚表的指针。不能保证下次运行程序时(可能在更改一些代码并重新编译之后)虚拟表将位于同一位置。更不用说,如果您自己更改了类,您的二进制转储将不再适合新的类定义。
作为一个更一般的经验法则:除非你做的是低级别的东西(比如与设备接口),在你的代码中有一个reinterpret_cast
几乎总是表明你在做一些你不应该做的事情。
处理这个问题的正确方法是遍历所有writer对象,并以定义良好的方式写入它们的数据。数据格式是二进制格式还是文本格式取决于您(如果有疑问,请选择文本格式,因为它更容易调试)。但重要的是,不要盲目地转储内存中的数据,而是要定义格式,并确保以该格式写入数据。