3

そのため、boost :: serializationライブラリを使用しています。デフォルトのコンストラクタがないため、クラスの構築方法をオーバーライドしようとしています。これはここに示されています。私には、関数がを取り、class* t新しく構築されたオブジェクトを指すように設定しているように見えます。私が間違っている場合、これは間違いなく私のエラーの原因です。

ただし、クラスを作成する唯一の方法は、別のクラスcreate()関数を使用することです。つまり、例のコードから逸脱する必要があります(これは、boost :: serialization名前空間に記載されています)。::new(t)my_class(attribute);

create関数を呼び出してt、返されたポインタと同じ値を設定しようとしましたが、の直後load_construct_data function、およびでserialization function、指定myClass&されたものが't'に設定したものと同じではないため、これは機能しないようです。

:: new(t)が実行していることを実行して、create関数を使用して作成されたオブジェクトがserialize / other関数に続くようにするにはどうすればよいですか?

4

2 に答える 2

2

あなたの質問(new(t) my_class(attribute))で言及されている構成は「配置新規」と呼ばれます。それが機能する方法はそれです

  1. t割り当てられたメモリ領域をすでに指している必要があります(配置newはデフォルトでは割り当てを行いません)
  2. のインスタンスはmy_class、そのメモリ位置に構築されます。

ただし、あなたの場合はコンストラクターを使用できないため、任意の形式を使用することnewは問題外です。しかし、別の方法(一種)があります。

newの配置はチャンクメモリを上書きするだけなので、すでに構築されているオブジェクトで同じことを行う通常の関数を使用できます。そのような関数はmemcpy

void * memcpy ( void * destination, const void * source, size_t num );

が指すメモリから。が指すメモリへのバイトmemcpy単位のコピーを実行するだけです。numsourcedestination

それで、あなたがこのコードで始めたとしましょうload_construct_data

my_class obj = other_class::create();

次に、この関数を使用して、で値をメモリ参照memcpyに「移動」することができます。objt

memcpy((void*)t, (void*)(&obj), sizeof(obj));

これが特定のクラスでどのように機能するかについては、ビット単位のコピーが「十分」であるかどうかなど、いくつかの詳細がありますが、これはあなたが尋ねたもので私が得た最高のものです。私が目にする問題の1つは、デストラクタがリソースを解放した場合、コピーが無効になる可能性があることです。

破壊で発生する可能性のある問題を説明するために、独自のディープコピー関数を作成できます。

void deepCopy( my_class * destination, const my_class * source );

の代わりにこれを呼び出しますmemcpy

:ここで何かを迷った場合は教えてください。現在、コードをテストするマシンがありません。

于 2011-08-13T12:07:31.193 に答える
1

デフォルトのコンストラクターがない場合、load_construct_data および save_construct データを使用すると、実際には shared_ptr インスタンスの使用が許可されます。私の見解では、memcpy と raw ポインターをいじる必要はありません。したがって、次のようなことができます

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

#include <memory>

class MyClass {
  public:
    explicit MyClass(std::string const &str) : m_str(str) {}
    MyClass() = delete;
    std::string str() const
    {
        return m_str;
    }
 private:
   std::string m_str;
};

namespace boost { namespace serialization {

    template<class Archive>
    void serialize(Archive &ar,
                   MyClass const & myClass,
                   unsigned int const) 
    {
        auto str = myClass.str();
        ar & str;
    }

    template<class Archive>
    void save_construct_data(Archive &ar,
                             MyClass const * myClass,
                             unsigned int const)
    {
        auto str = myClass->str();
        ar << str;
    }

    template<class Archive>
    void load_construct_data(Archive &ar,
                             MyClass * myClass,
                             unsigned int const)
    {
        std::string archived;
        ar >> archived;
        ::new(myClass)MyClass(MyClass(archived));
    }
}
}

int main(int argc, const char * argv[]) {

    std::shared_ptr<MyClass> myClass(new MyClass("hello!"));
    std::stringstream os;
    ::boost::archive::text_oarchive oa(os);
    oa << myClass;

    std::shared_ptr<MyClass> myClassB;
    std::stringstream is;
    is.str(os.str());
    ::boost::archive::text_iarchive ia(is);
    ia >> myClassB;

    return 0;
}
于 2016-05-05T12:17:15.390 に答える