Writing polymorphic class data to a file?

So, I have these classes. There is one base class, but it has / will have many and many derivatives, and these derived classes will also have derivatives. I would like to be able to have a function that writes my binary data to a file, but I'm not sure how to do this with a lot of derived classes.

I thought something like:

void writeData(ofstream & _fstream) { _fstream.write()//etc.. } 

But then every derived class that implemented this method would have to write all the data of the parent class, and this would duplicate a lot of code.

What is the best way to do this without overwriting all the previously written writeData() code?

+4
source share
4 answers

You can call the base class implementation from the derived class implementation:

 void Derived::writeData(ofstream & _fstream) { // Base class writes its data Base::writeData(_fstream); // now I can write the data that is specific to this Derived class _fstream.write()//etc.. } 
+9
source

A derived class can call base write methods to avoid code duplication. In fact, this may be the only way to go if some parent data is private, but is still indirectly used.

+4
source

If you want to avoid re-developing the entire implementation of the serialization functions of a derived class, you can go in another direction: from the base to derived classes:

The virtual class is provided in the base class to begin the serialization process. The client code calls this function with a pointer (or link). Also provide a virtual function that does serialization for the subclass. Call this function from the function of the base class Serialize .

(EDIT) If you want to provide standard functions for serializing subclasses, but still want to be able to provide specialized functions for specific cases, then the function that serializes the subclasses should not be pure virtual. However, after reading my OP, it seemed to me that each subclass would be required to provide this functionality. To simulate this requirement, I made the DoSerialize function pure virtual here.

Example:

 class Base { public: void Serialize() const; virtual void DoSerialize() = 0; }; class Derived : public Base { public: void DoSerialize() { /* MAGIC HAPPENS */ }; }; void Base::Serialize() const { /* .. do serialization of base class here, or at the end -- whichever is appropriate .. */ this->DoSerialize(); // serialize the derived class } /* ... */ Base* GetObject() { /* ... */ } int main() { Base* obj = GetObject(); obj->Serialize(); } 
+1
source

Ultimately, each derived class is responsible for ensuring that it is correctly serialized. A derived class may need to serialize some data before or after the base class, depending on its purpose. It may also be necessary to completely redefine the method of serializing base class data.

Look at it this way: the function performed here is serialization and de-serialization. The critical thing here is that it must be done correctly. Thus, the only class that is in a good position for this is one who has complete knowledge. In other words, this is your derived class.

So, there are times when you have to call Base :: writeData (), but regardless of whether you should do this, you should leave it completely to the derived class. Remember that you want your class hierarchy to satisfy some basic design principles . Once you succeed, it will be relatively easy.

0
source

Source: https://habr.com/ru/post/1383984/


All Articles