将多态类数据写入文件?

问题描述 投票:4回答:4

所以我有这些课程。有一个基类,但它有/将有很多很多衍生物,那些衍生类也可以有衍生物。我希望能够有一个将二进制数据写入文件的函数,但我不知道如何使用大量的派生类来完成这项工作。

我正在思考以下问题:

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

但是,实现此方法的每个派生类都必须编写它的所有父类的数据,这将复制大量代码。

如果不重写所有以前编写的writeData()代码,最好的方法是什么?

c++ derived-class ofstream
4个回答
9
投票

您可以从派生类实现中调用基类实现:

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..
}

4
投票

派生类可以调用基本的write方法来避免代码重复。事实上,如果某些父母的数据是私有的但仍然间接使用,这可能是唯一的方法。


1
投票

如果你想避免重新设计序列化函数的所有派生类的实现,你可以从另一个方向,从基类到派生类:

在您的基类中提供非virtual函数来启动序列化过程。客户端代码通过指针(或引用)调用此函数。还提供了一个为子类进行序列化的虚函数。从基类'Serialize函数调用该函数。

(编辑)如果要提供序列化子类的默认功能,但仍希望能够为特定情况提供专用功能,则序列化子类的函数不必是纯虚拟的。但是,通过我阅读你的OP,在我看来,需要每个子类来提供这个功能。为了模拟这个要求,我在这里将DoSerialize函数设为纯虚拟。

例:

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

0
投票

最终,每个派生类的责任是确保它已被正确序列化。派生类可能需要在基类之前或之后序列化某些数据,具体取决于其目的。它可能还想完全覆盖基类数据序列化的方式。

以这种方式看待它 - 这里执行的功能是序列化和反序列化。这里的关键是它需要正确执行。因此,唯一能够做到这一点的人才是具备完整知识的人。换句话说,它是你的派生类。

所以,有时你必须调用Base :: writeData(),但是你是否应该这样做应该完全取决于派生类。请记住,你想要的是你的班级层次结构satisfy some basic design principles。一旦你有了它,它应该相对容易。