4

所以我有这些课程。有一个基类,但它有/将有很多很多的派生类,这些派生类也可以有派生类。我希望能够拥有一个将其二进制数据写入文件的函数,但我不确定如何使用大量派生类来做到这一点。

我在想一些事情:

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

但是实现这个方法的每个派生类都必须写它所有的父类的数据,这会重复很多代码。

在不重写所有以前编写的writeData()代码的情况下,最好的方法是什么?

4

4 回答 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..
}
于 2011-11-30T20:42:44.363 回答
4

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

于 2011-11-30T20:43:42.283 回答
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();
}
于 2011-11-30T20:46:35.697 回答
0

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

这么看——这里执行的功能是序列化和反序列化。这里的关键是它需要正确执行。因此,唯一能够做到这一点的班级是拥有完整知识的班级。换句话说,它是您的派生类。

因此,有时您必须调用 Base::writeData(),但是否这样做应该完全由派生类决定。请记住,您想要的是让您的类层次结构满足一些基本设计原则。一旦你有了它,它应该相对容易。

于 2011-11-30T21:14:10.707 回答