多态序列化
Apache Fory™ 通过智能指针(std::shared_ptr 与 std::unique_ptr)支持多态序列化 ,为继承体系提供动态分派与类型灵活性。
支持的多态类型
std::shared_ptr<Base>:共享所有权,支持多态分派std::unique_ptr<Base>:独占所有权,支持多态分派- 集合类型:
std::vector<std::shared_ptr<Base>>、std::map<K, std::unique_ptr<Base>> - 可选类型:
std::optional<std::shared_ptr<Base>>
基础多态序列化
#include "fory/serialization/fory.h"
using namespace fory::serialization;
// 定义带虚函数的基类
struct Animal {
virtual ~Animal() = default;
virtual std::string speak() const = 0;
int32_t age = 0;
};
FORY_STRUCT(Animal, age);
// 定义派生类
struct Dog : Animal {
std::string speak() const override { return "Woof!"; }
std::string breed;
};
FORY_STRUCT(Dog, age, breed);
struct Cat : Animal {
std::string speak() const override { return "Meow!"; }
std::string color;
};
FORY_STRUCT(Cat, age, color);
// 含多态字段的结构体
struct Zoo {
std::shared_ptr<Animal> star_animal;
};
FORY_STRUCT(Zoo, star_animal);
int main() {
auto fory = Fory::builder().track_ref(true).build();
// 给所有类型注册唯一 type ID
fory.register_struct<Zoo>(100);
fory.register_struct<Dog>(101);
fory.register_struct<Cat>(102);
Zoo zoo;
zoo.star_animal = std::make_shared<Dog>();
zoo.star_animal->age = 3;
static_cast<Dog*>(zoo.star_animal.get())->breed = "Labrador";
auto bytes_result = fory.serialize(zoo);
assert(bytes_result.ok());
auto decoded_result = fory.deserialize<Zoo>(bytes_result.value());
assert(decoded_result.ok());
auto decoded = std::move(decoded_result).value();
assert(decoded.star_animal->speak() == "Woof!");
assert(decoded.star_animal->age == 3);
auto* dog_ptr = dynamic_cast<Dog*>(decoded.star_animal.get());
assert(dog_ptr != nullptr);
assert(dog_ptr->breed == "Labrador");
}
为多态注册类型
多态序列化需要为所有派生类型注册唯一 type ID:
fory.register_struct<Derived1>(100);
fory.register_struct<Derived2>(101);
推荐使用 type ID 的原因:
- 二进制表示更紧凑
- 类型查找和分派更快
- 与非多态类型的注册方式保持一致