2012-03-15 12 views
6

私は同様の質問を読みましたが、答えは見つかりませんでした。私はVisual Studio 2010を使い、1.47を増やしています。ここで派生オブジェクトのブーストシリアライゼーションは、派生のserialize()を呼び出さない

はコードですが、それは完全でコンパイル可能です:

#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

+0

テンプレートはありません。 –

+0

良い点 - テンプレートビットに気付かなかった! – Nick

答えて

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

ありがとう、しかし、最初の例外は、未登録のクラスの何かをスローし、もう1つは私のコードと基本的に同じことを行います。同じ結果... – CodeOrElse

+0

その後、 '<<"演算子はおそらく参照によって引数を取ることになり、私の理論は完全に間違っています。ごめんなさい。ベースクラスの登録を試しましたか?私は仕事中の現在のプロジェクトでこのようなものを使っていますが、詳細はすべて他の人が設定していますので、セットアップの部分については完全にはわかりません。 :/ – aldo

+0

基本クラスの登録を試したところ、うまくいきませんでした。 – CodeOrElse

0

のようにこれはないが、ポインタまたは参照ではなく、値によってシリアル化するために、あなたのコードを修正して見つけることができ厳密に答え、ちょうどkludgyの回避策。基底クラスの追加

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

マクロSTREAMTOARCHIVEを定義し、それぞれ、すべての派生クラスの1つにそれを置きます。

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

次にメインに、置き換えると

oa << base; 

base.StreamToArchive(oa); 

私が知っているいや、それはうまくそれが動作し、私はちょうどにそのSTREAMTOARCHIVEマクロを配置する必要があります。..醜いですが、派生クラス...私はそれと一緒に暮らすことができます...

しかし、それをオブジェクトに戻して構文解析すると、今ではNotherの...編集

をも問題:変更「これを」「*この」

関連する問題