Skip to content

unregister derived class exception when split design files #327

@wodadehencou

Description

@wodadehencou

I create a simple derived class example for serialization. The difference between example in document is that I split all files.
The whole example project is https://github.com/wodadehencou/boost-serialize-derived
And build can be rerun using

cmake -B build -S . -D CMAKE_BUILD_TYPE=Debug -D CMAKE_EXPORT_COMPILE_COMMANDS=tru
e
cmake --build build
./build/src/main

The wrong output is

terminate called after throwing an instance of 'boost::archive::archive_exception'
  what():  unregistered class - derived class not registered or exported
fish: Job 1, 'build/src/main' terminated by signal SIGABRT (Abort)

If I concat all files together in a single main.cpp, everything goes right.

I follow the instruction as in Document

  1. first create Base class
    1. make virtual ~Base() as virtual
    2. add serialize method to do nothing
    3. add BOOST_SERIALIZATION_ASSUME_ABSTRACT(Base) at the bottom of Base.h
#pragma once

#include "boost/serialization/access.hpp"
#include "boost/serialization/assume_abstract.hpp"

// 基类声明
class Base {
public:
  virtual void print() const = 0;
  virtual ~Base() = default;

private:
  friend class boost::serialization::access;

  template <class Archive>
  void serialize(Archive &ar, const unsigned int version) {
    // 基类无数据成员需要序列化
  }
};

BOOST_SERIALIZATION_ASSUME_ABSTRACT(Base)
  1. Then create DerivedA and DerivedB public derived from Base
    1. public derive
    2. add serialize method which calls base ar &boost::serialization::base_object<Base>(*this);
    3. add BOOST_CLASS_EXPORT_KEY(DerivedA) in DerivedA.h
    4. add BOOST_CLASS_EXPORT_IMPLEMENT(DerivedA) as the first line of DerivedA.cpp
#pragma once

#include "Base.h"
#include "boost/serialization/base_object.hpp"
#include "boost/serialization/export.hpp"

// 派生类 A
class DerivedA : public Base {
public:
  DerivedA() = default;
  DerivedA(int x) : data(x) {}
  virtual ~DerivedA() = default;

  void print() const override;

private:
  int data = 0;

  friend class boost::serialization::access;

  template <class Archive>
  void serialize(Archive &ar, const unsigned int version) {
    ar &boost::serialization::base_object<Base>(*this);
    ar & data;
  }
};

BOOST_CLASS_EXPORT_KEY(DerivedA)
#include "DerivedA.h"
#include "boost/serialization/export.hpp"
#include <iostream>

BOOST_CLASS_EXPORT_IMPLEMENT(DerivedA)

void DerivedA::print() const { std::cout << "DerivedA: " << data << std::endl; }
  1. Last, I create main.cpp and include Base.h, DerivedA.h, DerivedB.h, create a vector of std::unique_ptr. All serialization can not run successfully.
#include "Base.h"
#include "DerivedA.h"
#include "DerivedB.h"
#include <boost/archive/polymorphic_text_iarchive.hpp>
#include <boost/archive/polymorphic_text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/unique_ptr.hpp>
#include <boost/serialization/vector.hpp>
#include <fstream>
#include <vector>

// BOOST_CLASS_EXPORT_IMPLEMENT(DerivedA)
// BOOST_CLASS_EXPORT_IMPLEMENT(DerivedB)

int main() {

  // 创建多态对象集合
  std::vector<std::unique_ptr<Base>> original;
  original.emplace_back(new DerivedA(42));
  original.emplace_back(new DerivedB("hello"));
  original.emplace_back(new DerivedA(100));

  // 序列化到文件
  {
    std::ofstream ofs("archive.txt");
    boost::archive::text_oarchive oa(ofs);
    oa << original; // 自动处理多态指针
  }

  // 从文件反序列化
  std::vector<std::unique_ptr<Base>> restored;
  {
    std::ifstream ifs("archive.txt");
    boost::archive::text_iarchive ia(ifs);
    ia >> restored; // 自动重建正确类型
  }

  // 验证反序列化结果
  for (const auto &ptr : restored) {
    ptr->print();
  }

  return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions