0

我有以下课程

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 添加一个 Books 向量

我保存它:

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 个元素的向量,但它无法告诉我这些元素的数据......

谁能帮我一把?

4

1 回答 1

2

永远不要尝试将 C++ 类存储为二进制转储。

首先,std::vector 包含一个指向实际数据的指针和一个大小。您写入文件的只是指针和大小;实际数据没有写入。读回数据后,指针指向内存中的某个地方,但那个地方没有数据。

但即使您的数据都存储在一个地方,编写二进制转储文件仍然不是一个好主意。如果您的类具有虚成员函数,则内存中的对象包含指向相应虚表的指针。不能保证下次运行程序时虚拟表会在同一个地方(可能在更改一些代码并重新编译之后)。更不用说,如果您自己更改了类,您的二进制转储将不再适合新的类定义。

作为更一般的经验法则:除非您正在做低级的事情(例如与设备交互),否则reinterpret_cast在您的代码中几乎总是表明您正在做一些您不应该做的事情。

处理此问题的正确方法是遍历所有编写器对象并以明确定义的方式写入它们的数据。数据格式是二进制还是文本格式取决于您(如果有疑问,请选择文本格式,如果只是因为它更易于调试)。但重要的是不要盲目地转储内存中的数据,而是实际定义格式并确保数据以该格式写入。

于 2013-06-09T00:32:47.217 回答