मेरे पास चार वर्ग (A
, B
, C
और D
) क्लासिक डायमंड पैटर्न और Container
कक्षा के बाद unique_ptr<A>
है। मैं 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 ' है, और सबसे अधिक व्युत्पन्न प्रकार '* ओबीजे' 'ए' है। 'बी 'कहाँ कूदता है? – aschepler