(Bu soru this one'a çok benziyor, ancak bu seferserileştirici kurucuyu Child
başlatma listesinde çağırıyorum). Bir Child
hiçbir yeni veri Serileştirilecek ekleyen bir durumda Yapılandırıcı hiyerarşisini serileştirme
Parent
ben
Child
doğrudan yanı
Parent
nesne seri edebilmek istiyorum bir varsayılan kurucu ve yok çocuk ne de ebeveyn varsayılan kurucuya sahip, biz başlatma listesinde (aynı zamanda deserializing yapıcısı kullanılarak) çocuk deserializing yapıcı ebeveyn başlatır aşağıdaki deseni, kullanmalıdır gibi görünüyor:
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>
class Parent
{
public:
double mParentData;
Parent(const double data) : mParentData(data) {}
template<typename TArchive>
Parent(TArchive& archive)
{
archive >> *this;
}
template<class TArchive>
void serialize(TArchive& archive, const unsigned int version)
{
archive & mParentData;
}
};
class Child : public Parent
{
public:
Child(const double data) : Parent(data) {}
template<typename TArchive>
Child(TArchive& archive) : Parent(archive)
{
// Do nothing, as the only data to read is in Parent
}
template<class TArchive>
void serialize(TArchive& archive, const unsigned int version)
{
// Let the parent do its serialization
archive & boost::serialization::base_object<Parent>(*this);
// Nothing else to do, as the only data to read/write is in Parent
}
};
int main()
{
Child child(1.2);
{
std::ofstream outputStream("test.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << child;
outputStream.close();
}
{
std::ifstream inputStream("test.txt");
boost::archive::text_iarchive inputArchive(inputStream);
Child childRead(inputArchive);
std::cout << "childRead:" << std::endl
<< childRead.mParentData << std::endl; // Outputs 0 (expected 1.2)
}
return 0;
}
Yani çağrı zinciri gerekir (ve yapar) gibi görünün:
Çıktı:
- Çocuk :: serialize()
- Veli :: serialize()
Girdi:
- Çocuk (arşiv)
- Üst (arşiv) .210
- Veli :: serialize()
Ancak mParentData
ben 1.2
olmasını beklediğiniz childRead
yılında 0
olarak sona erer.
Hata gören var mı?
----------- DÜZENLEME -----------
olarak çocuk seri hale getirmek hiçbir ek veriye sahip durumda @stijn tarafından işaret , desen çocuk ve ebeveyn hem seri hale getirmek veriye sahip olduğunda durumda, Ancak
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>
class Parent
{
public:
double mParentData;
Parent(const double data) : mParentData(data) {}
template<typename TArchive>
Parent(TArchive& archive)
{
archive >> *this;
}
template<class TArchive>
void serialize(TArchive& archive, const unsigned int version)
{
archive & mParentData;
}
};
class Child : public Parent
{
public:
Child(const double data) : Parent(data) {}
template<typename TArchive>
Child(TArchive& archive) : Parent(archive)
{
// Do nothing, as the only data to read is in Parent
}
};
int main()
{
Child child(1.2);
{
std::ofstream outputStream("test.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << child;
outputStream.close();
}
{
std::ifstream inputStream("test.txt");
boost::archive::text_iarchive inputArchive(inputStream);
Child childRead(inputArchive);
std::cout << "childRead:" << std::endl
<< childRead.mParentData << std::endl; // Outputs 0 (expected 1.2)
}
return 0;
}
ve ikisi de bir varsayılan kurucu yok: biz sadece bu gibi tamamen Child
den serialize()
fonksiyonunu kaldırabilir Aşağıdaki gibi bir şey olması gerektiği gibi görünüyor, ama tam olarak değil. Child
serileştirici yapıcıda, Parent
serileştirici yapıcıyı çağırıyoruz, aynı zamanda Parent::serialize()
işlevini çağıran Child::serialize()
işlevini çağırıyoruz, bu nedenle Parent
etkin bir şekilde Parent
iki kez serivermeyi deneyecektir. Bu yanlış davranış burada gösterilmiştir: Bir şekilde gibi görünüyor
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>
class Parent
{
public:
double mParentData;
Parent(const double data) : mParentData(data) {}
template<typename TArchive>
Parent(TArchive& archive)
{
archive >> *this;
}
template<class TArchive>
void serialize(TArchive& archive, const unsigned int version)
{
archive & mParentData;
}
};
class Child : public Parent
{
public:
double mChildData;
Child(const double parentData, const double childData) : Parent(parentData), mChildData(childData) {}
template<typename TArchive>
Child(TArchive& archive) : Parent(archive)
{
archive >> *this;
}
template<class TArchive>
void serialize(TArchive& archive, const unsigned int version)
{
// Let the parent do its serialization
archive & boost::serialization::base_object<Parent>(*this);
// Do the child serialization
archive & mChildData;
}
};
int main()
{
Child child(1.2, 3.4);
{
std::ofstream outputStream("test.txt");
boost::archive::text_oarchive outputArchive(outputStream);
outputArchive << child;
outputStream.close();
}
{
std::ifstream inputStream("test.txt");
boost::archive::text_iarchive inputArchive(inputStream);
Child childRead(inputArchive);
std::cout << "childRead:" << std::endl
<< childRead.mParentData << std::endl // Outputs 0.2 (expected 1.2)
<< childRead.mChildData << std::endl; // Outputs 3.4 correctly
}
return 0;
}
biz Child
deserializing kurucusundan Child::serialize()
farklı bir sürümünü çağırmanız gerekir? Veyaserileştirici kurucudan çağrılırsa Parent
'u Child::serialize()
'dan açıkça kaldırmayacak şekilde bir bayrak ayarlayın?
template<class TArchive>
void serialize(TArchive& archive, const unsigned int version)
{
// Let the parent do its serialization
Parent::serialize(archive, version);
// Do the child serialization
archive & mChildData;
}
Belki bir şey özlüyorum ama eğer 'serialize() işlevini Çocuk'ta kaldırırsanız, beklendiği gibi çalışır. Artık serileştirecek hiçbir şey olmadığından fonksiyona gerek yok, yorumlarda kendiniz söylediğiniz gibi, ve hatta üst sınıf çağrılarının '&' ile değil 'serialize' ile yapılması gerektiğini düşünmüyordum bile , yani, aramayı çağırmanız gerekir Ana :: serileştirmek veya yükseltmek :: serialization :: serialize (arşivi, yükseltmek :: serialization :: base_object (* this), version); Parent :: serialize zaten nihayet çağıran –
stijn
Tam olarak doğru sen @stijn, seri hale getirmek için veri olan tek bir veli olduğunda, tamamen "Çocuk :: serialize()" kaldırmak için iyi çalışıyor. Çocuğun serileştirmek için ek veriye sahip olduğu soruna örnek bir vaka ekledim. Çocuk :: serialize() 'den' Parent :: serialize (arşivi, versiyon) 'aramayı denedim, ancak bu segfaults. (ve boost :: serialization :: serialize ile aynıdır (arşivi, boost :: serialization :: base_object (* bu), sürüm); ') –
Bu durumda, Lukas'ın yanıtının gitmenin yolu olduğunu düşünüyorum. else işaretçiler/kayıt türleri, ve belgeler – stijn