简体   繁体   中英

Storing complex structure to file

I have the following class

class WriterCollection
{
std::vector<Writer> arts;
public:
WriterCollection(void);
~WriterCollection(void);


void DisplayMenu();
void AddWriter();
void EditWriter();
void ShowWriterList();
int SearchWriter(std::string name = "");
};

I tried to save it on a binary file

so I have

WriterCollection ac;
ac.AddWriter();
ac.AddWriter();
ac.AddWriter();

What happens is that it asks me for a name for each Writer, I am also able to add a vector of Books to each one

and I save it:

std::ofstream output_file("db.data", std::ios::binary);
output_file.write((char*)&ac, sizeof(ac));
output_file.close();

when the program starts I try to read it...

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 ) );

It correctly says that inside my collection there is a vector with 3 elements but it's unable to tell me the data on those elements...

Can anyone give me a hand?

Never try to store a C++ class as binary dump.

First, std::vector contains a pointer to the actual data, and a size. What you've written to the file is just the pointer and the size; the actual data is not written. After reading back the data, the pointer is pointing somewhere in memory, but there's no data at that place.

But even if your data were all stored in one place, it is still a bad idea to write a binary dump. If your class has virtual member functions, the object in memory contains a pointer to the corresponding virtual table. There's no guarantee that the virtual table will be at the same place the next time you run your program (possibly after changing some code and recompiling). Not to mention that of course if you ever change the class yourself, your binary dumps will no longer fit the new class definition.

As a more general rule of thumb: Unless you are doing low level stuff (like interfacing with devices), having a reinterpret_cast in your code almost always indicates that you're doing something which you shouldn't do.

The correct way of handling this is to iterate through all your writer objects and write their data in a well-defined way. Whether the data format is then a binary or a text format is up to you (when in doubt, choose a text format, if only because it is easier to debug). But the important thing is that you don't blindly dump the in-memory data, but actually define the format and make sure the data is written in that format.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM