У меня есть древовидная структура, которая должна быть сериализована. Типичная структура, причем каждый узел имеет parent
членов и children
векторов. parent
является исходным указателем на класс, и children
: vector
s shared_ptr
s. Теперь кажется, что сериализация работает нормально, но de -сериализация оставляет parent
членов неинициализированных (указывает на 0xcccccccc
или 0x00000000
).boost :: сериализация и циклическая десериализация ссылок
В parent
членах загружаются, когда фактический родительский объект еще не закончил десериализации, то есть ребенок parent
элемента загружается через запрос десериализации родителя children
. Поскольку это циклично, мне было интересно, нужно ли мне принимать специальные меры для его работы.
Спасибо за помощь.
Update: Это как моя функция сериализация выглядит следующим образом:
template <typename Archive>
void serialize(Archive& archive, GameCore::GameObject& t, const unsigned int version)
{
archive & boost::serialization::base_object<GameCore::Object>(t);
archive & boost::serialization::base_object<GameCore::Updatable>(t);
archive & t.parent;
archive & t.transform;
archive & t.components;
archive & t.children;
}
Если я закомментировать archive & t.children
, parent
получает правильно заполнены.
Обновление 2: Хорошо, мне удалось превратить это в минимальный образец, который представляет проблему. Необходимо скомпилировать:
#include <boost\archive\binary_oarchive.hpp>
#include <boost\archive\binary_iarchive.hpp>
#include <fstream>
#include <memory>
#include <vector>
class A
{
public:
A() {}
A(const A& rhs) = delete;
int someInt = 0;
A* parent = nullptr;
std::vector<A*> children;
template <class Archive>
void serialize(Archive& archive, const unsigned int version)
{
archive & someInt;
archive & parent;
int count = children.size();
archive & count;
children.resize(count);
for (int i = 0; i < count; ++i)
{
A* ptr = children[i];
archive & ptr;
children[i] = ptr;
}
}
};
int main()
{
A* newA = new A();
newA->someInt = 0;
A* newPtr = new A();
newPtr->someInt = 5;
newPtr->parent = newA;
newA->children.push_back(newPtr);
// Save.
std::ofstream outputFile("test", std::fstream::out | std::fstream::binary);
if (outputFile.is_open())
{
boost::archive::binary_oarchive outputArchive(outputFile);
// Serialize objects.
outputArchive << newA;
outputFile.close();
}
delete newA;
delete newPtr;
A* loadedPtr = nullptr;
// Load.
std::ifstream inputFile("test", std::fstream::binary | std::fstream::in);
if (inputFile && inputFile.good() && inputFile.is_open())
{
boost::archive::binary_iarchive inputArchive(inputFile);
// Load objects.
inputArchive >> loadedPtr;
inputFile.close();
}
return 0;
}
Пройдите код. Ребенок parent
остается нулевым, всегда.
Если кто-нибудь, * кто-то может реплицировать эту проблему, пожалуйста, дайте мне знать, потому что это сводит меня с ума! –
FWIW: программа в обновлении 2 (плюс некоторые утверждения для проверки) [работает правильно в Coliru] (http://coliru.stacked-crooked.com/a/69a02441a7048015), поэтому проблема в вашем конце. – Casey
Тогда что, черт возьми, я делаю неправильно? Я тестировал это на двух машинах, двух разных сборках Boost ... Может, я ошибаюсь? –