5

ジェネリック クラスのポインターのリストとして属性を持つクラスをシリアル化したい

これは、ジェネリック クラスの派生元の親クラスです。

class Base{

    public :

        friend class boost::serialization::access;

        virtual ~Base(){}

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

        virtual string Getid() = 0 ;

};

ジェネリック クラス:

template<typename T>
class GenericBase : public Base
{
    public:

        friend class boost::serialization::access;

        GenericBase<T>(string id){}
        ~GenericBase(){}

        string id;

        vector<T> data

        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & boost::serialization::base_object<Base>(*this);
            ar & BOOST_SERIALIZATION_NVP( id);
            ar & BOOST_SERIALIZATION_NVP( data);

        }

        string Getid() { return id; }

};

シリアライズしたいクラス

class Use
{
    public:

        friend class boost::serialization::access;

        int Id;

        map<string, Base*> BaseDatas;

        Use();
        ~Use();

};

したがって、ブーストシリアライゼーションドキュメント(http://www.boost.org/doc/libs/1_43_0/libs/serialization/doc/serialization.html#derivedpointers)を読んだ後、シリアライゼーションコードでこれを試しました:

main(){

   Use u = Use();

   std::ofstream ofs(filename, ios::binary);

   // save data to archive

   boost::archive::binary_oarchive oa(ofs);

   oa.template register_type<GenericBase<Type1> >();
   oa.template register_type<GenericBase<Type2> >();
   oa.template register_type<GenericBase<Type3> >();

   oa<<u;

}

メッセージを頂きました、

エラー: 'template' (曖昧さ回避ツールとして) はテンプレート内でのみ許可されます

、だから私は交換した

oa.template register_type >();

oa.register_type();

それは機能し、テキストとバイナリで保存できました(データを確認しました)

今ロードするために、私はこれらの行を使用しました:

main(){

    Use u;

    std::ifstream ifs(filename, ios::binary);

    // load data

    ia.register_type<GenericBase<Type1> >();

    boost::archive::binary_iarchive ia(ifs);

    ia>>u;

}

それは私にエラーを投げました:

エラー: 'GenericBase::GenericBase()' の呼び出しに一致する関数がありません

このサンプルhttp://www.boost.org/doc/libs/1_43_0/libs/serialization/doc/serialization.html#constructorsのように、保存と読み込みの2つのメソッドをオーバーライドする必要があると誰かが私に言いました

namespace boost { namespace serialization {
template<class Archive>
inline void save_construct_data(
    Archive & ar, const my_class * t, const unsigned int file_version)
    {
        // save data required to construct instance
        ar << t->m_attribute;
    }

template<class Archive>
inline void load_construct_data(
    Archive & ar, my_class * t, const unsigned int file_version)
    {
        // retrieve data from archive required to construct new instance
        int attribute;
        ar >> attribute;
        // invoke inplace constructor to initialize instance of my_class
       ::new(t)my_class(attribute);
    }
}} // namespace ...

しかし、どこでそれらを定義する必要がありますか? Useクラスの宣言では?メンバーとどう付き合うか

map<string, Base*> BaseDatas;

?

ご協力いただきありがとうございます ;)

4

2 に答える 2

4

いくつかのダミーデータを使用して、失敗したコードの実用的な(カットアンドペースト)例を提供すると、コメントが簡単になります...

しかし、とにかく答えようとします...

Boost.serialisationはGenericBasesのデフォルトコンストラクターを呼び出そうとしていますが、指定しないため失敗します。Boost.serialisationは最初にオブジェクトを作成し(または今すぐ試行し)、次にファイルを読み取り、変数を設定します。

保護されたデフォルトコンストラクターを宣言してみることができます。このコンストラクターは、ブーストがアクセスを介してアクセスできる必要があります。

于 2010-10-08T09:16:47.847 に答える
0

しかし、どこでそれらを定義する必要がありますか?

それらは任意のヘッダーで定義できます

メンバーとどう付き合うか…

BOOST_CLASS_TRACKING を使用してポインターを追跡するブーストを取得できると思います...

http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/special.html#objecttracking

于 2010-08-02T14:12:36.337 に答える