2011-11-30 81 views
4

所以我有這些類。有一個基類,但它有/將有很多很多的衍生物,而這些派生類也可以有衍生物。我希望能夠有一個函數,他們的二進制數據寫入文件,但我不知道如何做到這一點與很多很多的派生類。將多態類數據寫入文件?

我想沿着線的東西:

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

但隨後每個派生類實現此方法會寫它的所有父類的數據,這將是大量重複的代碼。

什麼是做,而無需重寫所有先前寫入writeData()代碼的最佳方式?

回答

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

我喜歡這個想法,但不會失敗,如果基礎沒有派生類?我認爲將其簡單地虛擬化會更安全,而不是純粹的。 – lowq

+0

我曾經想過,出於某種原因,我現在無法辨別,OP是在使用ABC。我會編輯,因爲他不是很明顯。 –

+0

啊,在我的情況下,有沒有衍生物的對象。雖然仍然有效。 – lowq

0

歸根結底,這是每一個派生類的責任,以確保它已正確序列化。派生類可能需要在基類之前或之後序列化一些數據,具體取決於其目的。它也可能想完全覆蓋基類數據序列化的方式。

看它這樣 - 這裏正在執行的功能是序列化和反序列化。這裏至關重要的是它需要正確執行。因此,唯一能夠做到這一點的班級是具有完整知識的班級。換句話說,它是你的派生類。

所以,有些時候,你將不得不調用基::寫數據(),但你是否這樣做,應該留給完全取決於派生類。請記住,你想要的是你的班級層次爲satisfy some basic design principles。一旦你有了,它應該是相對容易的。