私は古典的な菱形のパターンに続いてを含むContainer
クラスの4つのクラス(A
,B
,C
およびD
)を持っています。私はこれらのクラスをcerealシリアライズライブラリを使用してシリアル化したいと思います。バーチャル継承と多型:穀物図書館はオブジェクトレイアウトを乱していますか?
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(...)
}
}
すべてのクラスは穀物save
とload
機能を持っていますが、彼らはこの例で使用される唯一のもので、私は唯一、B
とContainer
のためにそれらが含まれています。
次のように私はこれらのクラスを使用します。
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++プログラムでは、特定のオブジェクトのフィールドのアドレスが変更されることはありますか?
なぜ 'ar(obj)'が 'B :: save(ar)'を呼び出すのですか? – aschepler
@ascheplerシリアルライブラリはそれを行います:http://uscilab.github.io/cereal/serialization_functions.html – Xion345
私は、 'obj'が' std :: unique_ptr 'であり、最も派生した' * * objはAである。 'B'はどこに飛び込むの? – aschepler