2016-03-01 111 views
0

我想序列化一個沒有默認構造函數的派生類。我正在使用反序列化構造函數模式。我讀過你必須註冊派生類的類型,所以我在輸出檔案中這樣做(outputArchive.register_type<Point>();)。但是,當試圖向輸入存檔註冊相同類型時,我得到一個編譯器錯誤,說Point沒有默認構造函數(它沒有)。我們在這種情況下做什麼?註冊一個沒有默認構造函數的類型

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/shared_ptr.hpp> 
#include <boost/serialization/base_object.hpp> 

#include <fstream> 

class AbstractPoint 
{ 
public: 
    virtual ~AbstractPoint(){} 
    virtual void DoSomething() = 0; 

    template<class TArchive> 
    void serialize(TArchive& archive, const unsigned int version) 
    { 
     // do nothing 
    } 
}; 

class Point : public AbstractPoint 
{ 
public: 

    Point(const double data) : mData(data) {} 

    void DoSomething(){} 

    template<class TArchive> 
    Point(TArchive& archive) 
    { 
     archive >> *this; 
    } 

    template<class TArchive> 
    void serialize(TArchive& archive, const unsigned int version) 
    { 
     // Without this, we get unregistered void cast 
     archive & boost::serialization::base_object<AbstractPoint>(*this); 

     archive & mData; 
    } 

    double mData; 
}; 

int main() 
{ 
    std::shared_ptr<AbstractPoint> point(new Point(7.4)); 

    std::ofstream outputStream("test.txt"); 
    boost::archive::text_oarchive outputArchive(outputStream); 
    outputArchive.register_type<Point>(); 
    outputArchive << point; 
    outputStream.close(); 

    std::ifstream inputStream("test.txt"); 
    boost::archive::text_iarchive inputArchive(inputStream); 
    //inputArchive.register_type<Point>(); // Compiler error: no Point::Point() 
    std::shared_ptr<AbstractPoint> pointRead(new Point(inputArchive)); 

    Point* castedPoint = dynamic_cast<Point*>(pointRead.get()); 
    std::cout << "Data: " << castedPoint->mData << std::endl; 
    return 0; 
} 
+1

僅供參考我在這裏與分裂這個問題,http://stackoverflow.com/questions/35753953/common-confusions-with-serializing-polymorphic-types –

回答

0

在一個類型沒有默認構造函數的情況下,你可以使用save_construct_dataload_construct_data

請注意,這些將只有永遠適用於通過指針序列化(出於顯而易見的原因)。

例子在這裏:boost serialization of non-default constructible typesmore

+0

我學到了其他一天(http://stackoverflow.com/questions/35722135/deserializing-construtor-doesnt-read-data-correctly)我應該使用反序列化構造函數模式。所以你說這個模式只在不序列化多態類型指針時才起作用? –

+0

@DavidDoria你的問題代碼和答案代碼似乎是一個典型的Boost序列化代碼給我。問題代碼因答案中陳述的原因而中斷。我很想說答案代碼仍然是錯誤的(很難讓它工作可靠;我甚至不能開始考慮如何將它與容器的Boost序列化結合起來)。所以是的,那個答案沒有回答你真正的問題,因爲你提出了錯誤的問題。 – sehe

+0

不使用'save/load_construct_data'的一點是,如果你沒有/想要一個指針,那麼你就不需要像你想要的那樣「僞造」/想要一個指針來完成序列化。 –

相關問題