2012-03-15 68 views
6

我已經閱讀了大量類似的問題,但沒有找到答案。我正在使用Visual Studio 2010並提升1.47。派生對象的boost序列化不調用派生的序列化()

下面的代碼,它是完整的,可編譯:

#include "stdafx.h" 

#include <string> 
#include <sstream> 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 

#include <boost/serialization/export.hpp> 

using namespace std; 

class BaseObject 
{ 
public: 

    BaseObject(void) { }; 
    virtual ~BaseObject(void) { }; 

    template<class Archive> 
     void serialize(Archive &ar, const unsigned int version) 
     { /* nothing happens here */ }; 
}; 

class DerivedObject : public BaseObject 
{ 
public: 

    string text; 

public: 

    DerivedObject(void) { }; 
    ~DerivedObject(void) { }; 

    template<class Archive> 
     void serialize(Archive &ar, const unsigned int version) 
     { 
      ar & text; 
     }; 
}; 

BOOST_CLASS_EXPORT(DerivedObject) 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    DerivedObject der; 
    der.text = "Testing!"; 

    std::ostringstream os; 
    boost::archive::text_oarchive oa(os); 
    oa.register_type<DerivedObject>(); 

    // I made a DerivedObject, but I'm casting it to a BaseObject 
    // as the serialization code should not have to know what type it is 
    BaseObject *base = &der; 
    // now serialize it 
    oa << *base; 

    printf("serialized: %s\r\n",os.str().c_str()); 

    return (0); 
} 

你可以看到它的真正簡單,我添加了是應該確保DerivdObject ::序列化BOOST_CLASS_EXPORT和oa.register_type魔術()被稱爲即使它不是一個虛擬的方法..但仍然只調用BaseObject中的serialize()。一個特定於Visual C++的問題?請指教?

+1

不應該將'BaseObject :: serialize'標記爲'virtual'? – Nick 2012-03-15 10:45:25

+0

不,它是一個模板,它不可能 – 2012-03-15 10:50:41

+0

好點 - 沒有注意到模板位! – Nick 2012-03-15 10:53:46

回答

2

正如描述的boost serialization documentation你需要告訴你的派生類中調用基類的序列碼。只需編寫你的派生類序列化方法,如下所示:

template<class Archive> 
    void serialize(Archive &ar, const unsigned int version) 
    { 
     ar & boost::serialization::base_object<BaseObject>(*this); 
     ar & text; 
    }; 
0

我還沒有在調試器或任何東西中試過這個,但它看起來可能是切片的情況。也許你可以找到通過修改代碼以指針或引用,而不是通過值序列化,像這樣......

BaseObject *base = &der; 
oa << base; // Serialize a pointer 

......或者......

BaseObject& base = der; 
oa << base; // Serialize a reference 
+0

謝謝,但第一個引發異常,未註冊類的東西,另一個與我的代碼基本相同。同樣的結果... – CodeOrElse 2012-03-16 12:04:21

+0

我後來意識到'''操作符可能通過引用引用參數,這使我的理論完全錯誤。抱歉。你有沒有試過註冊基類?我正在使用這個東西在工作中的當前項目,但所有的細節都由其他人設置,所以我不完全清楚在設置部分。 :/ – aldo 2012-03-16 16:15:31

+0

我剛剛嘗試註冊基類,它沒有工作,對不起。 – CodeOrElse 2012-03-16 21:12:06

0

這不是絕對是一個答案,只是一個可行的解決方法。

在基礎類添加:

virtual void StreamToArchive(boost::archive::text_oarchive &oa) = 0; 

然後定義一個宏STREAMTOARCHIVE並把它的每一個派生類中的一個。

#define STREAMTOARCHIVE void StreamToArchive(boost::archive::text_oarchive &oa) { oa << *this; } 

然後在主,更換

oa << base; 

base.StreamToArchive(oa); 

是啊,我知道,這是醜陋的,但..還有它的作品,我只是把那個STREAMTOARCHIVE宏派生類...我可以忍受那個...

但是然後...解析它回到一個對象,現在這是一個諾特爾重要...

編輯:改變「這個」到「*這個」