2016-08-02 69 views
-1

我想學習如何序列化C++對象。 在閱讀了幾篇文章之後,使用boost序列化函數和使用加載/保存函數進行歸檔似乎是一個不錯的主意。不過,我想避免使用boost庫。不知道它的字段序列化C++對象

概念,我可以保存對象不知道它的領域。在C++中沒有反射,存儲對象的唯一方法是知道它的所有類成員。

可以使用stringstream並重載<<運算符將對象轉換爲字符串,我可以直接保存對象。

謝謝,K.

+2

號在沒有反思的語言,除非你知道這些成員是你不能做的任何成員。 –

+1

有人必須知道它的領域,可能本身。你可以這樣做,以便調用者不需要知道這些字段,並且有一個函數用於讀寫。請注意,序列化有許多棘手的問題,例如版本控制等,這些問題使得萬能庫存在問題。 – Yakk

回答

1

在概念上,可以我保存的對象不知道它的字段。

不,你不能。

在C++中沒有反射,存儲對象的唯一方法就是知道它的所有類成員。

是的。最好的辦法是離開的知識封裝在類本身:

class MyClass { 
public: 
    std::ostream& put(std::ostream& os) const { 
     os << field1 << " " << field2 << std::endl; 
     return os; 
    } 
    friend std::ostream& operator<<(std::ostream& os, const MyClass& myclass) { 
     return myClass.put(os); 
    } 
private: 
    int field1; 
    double field2; 
}; 
+0

我不喜歡這種設計,因爲讀寫違反幹。添加一個助手模板,並且具有讀取版本讀取和寫入版本寫作以改善事物的io功能。 – Yakk

+0

@Yakk你總是可以添加更多的間接層次,這並不妨礙你知道實際的字段在那裏(QED在這裏)。 –

+0

這變得複雜得很快(例如,想象一下,如果該類有一個字符串字段) - 我認爲它會更好地執行'通過調用每個命名成員的輔助功能put',和輔助超載支持任何成員類型你將使用 –

0

你可以遵循的方法是通過默認支持元組的喜好和iterables。

有一個read_archive和write_archive首先做看中SFINAE檢測到支持for(:)循環,即是元組,像它們支持std::tuple_size和ADL get<I>類型和類型。

這也線與在C++ 17結構結合支持一種形式。

接下來,有一個to_tie sfinae adl基於實現啓用,檢查to_tie()to_tie(.)。如果是這樣並且可讀/可寫,則使用它。

在有可能的地方包括archive_io功能的ADL查找,這樣你就可以明確地寫自己的IO。

的目標是自動存檔儘可能和你不能讓它容易撰寫。