6

古典的なひし形パターンに続く4 つのクラス ( A、および) とB、を含むクラスがあります。シリアルシリアル化ライブラリを使用してこれらのクラスをシリアル化したいです。CDContainerunique_ptr<A>

struct A {int f1; int f2; int f3}

struct B : public virtual A {
    template<typename Archive>
    inline void save(Archive& ar) const {
        std::cerr << "Saving Obj: " << this << std::endl;
        std::cerr << "This: " << &(this->f1) << " " 
            << &(this->f2) << " " << &(this->f3) << std::endl;
        std::cerr << "This: " << this->f1 << " " 
            << this->f2 << " " << this->f3 << std::endl;
    };
}
};

struct C : public virtual A {};

struct D : public B, public C {};

#include <cereal/archives/binary.hpp>
CEREAL_REGISTER_TYPE(B);
CEREAL_REGISTER_TYPE(C);
CEREAL_REGISTER_TYPE(D);

struct Container {
    std::unique_ptr<A> obj;

    template<typename Archive>
    inline void save(Archive& ar) const {
        std::cerr << "Saving Container" << std::endl;
        std::cerr << "Obj Addr: " << obj.get() << std::endl;
        std::cerr << "Obj: " << &(obj->f1) << " " << &(obj->f2) 
            << " " << &(pq->f3) << std::endl;
        std::cerr << "Obj: " << " " << pq->sq_count << " " << pq->sq_bits 
            << " " << pq->dim << std::endl;
        ar(obj); // Call serialization for obj, ie B.save(...)
    }
}

すべてのクラスには cerealsaveとfunctions がありますが、この例で使用されているのは と だけなので、とloadにのみ含めました。BContainer

これらのクラスを次のように使用します。

std::unique_ptr<A> obj(new B);
obj->f1 = 8;
obj->f2 = 8;
obj->f3 = 128;
std::unique_ptr<Container> db(new Container);
db.obj = std::move(obj);

std::ofstream out_file(out_filename);
cereal::BinaryOutputArchive out_archive(out_file);
out_archive(db);

そして、次の出力が得られます。

Saving Container
Obj Addr: 0x23d2128 
Obj: 0x23d2130 0x23d2134 0x23d2138 // Fields adresses (f1,f2,f3)
Obj:  8 8 128 // Fields values
Saving Obj: 0x23d2128 // Same object
This: 0x23d2118 0x23d211c 0x23d2120 // Different field adresses !
This: 4293296 0 37569440 // Garbage

私の質問は次のとおりです。これは穀物のバグである可能性が高いですか、それとも仮想継承で取得できないものがありますか?

特定のオブジェクトのフィールドのアドレスが C++ プログラムで変更されることは予想されますか?

4

1 に答える 1