C++ 运行时反射系统设计与实现

9 阅读1分钟

一、引言

在很多高级语言(如 C#/Java)中,“反射”是一种内省机制,允许程序在运行时查看和操作对象的结构与行为(如类名、字段、方法等)。而 C++ 作为静态语言,默认并不支持强反射机制

尽管 C++ 提供 RTTI(如 typeiddynamic_cast),但其功能非常有限,并且很多高性能或嵌入式环境都禁用了 RTTI。

本文将从零开始,实现一个纯 C++ 的运行时反射系统,不依赖 RTTI,可实现字段注册、类型名称、对象属性遍历、动态构造等能力。

二、反射系统的应用场景

场景

用途

编辑器

属性面板展示与绑定

脚本接口

反射 C++ 对象给 Lua/Python

序列化

将对象自动转为 JSON/XML/Binary

插件系统

不同模块之间的统一字段解析与操作

网络通信

自动化消息结构注册与生成

三、目标功能概览

我们的运行时反射系统应具备以下能力:

  • 注册类型信息(类名、字段)

  • 动态构造对象(new 及析构)

  • 遍历字段,获取/设置值

  • 查询字段类型、名称、偏移量

  • 跨模块兼容性(不依赖 RTTI)

四、核心设计思路

设计三个核心类:

  1. Type:表示一个类的信息

  2. Field:表示类的一个字段(属性)

  3. TypeRegistry:集中管理所有注册的类型

我们通过宏 + 模板封装类信息,在运行时自动注册。

五、字段描述结构 Field

cpp复制编辑struct Field {
    std::string name;
    std::string type;
    size_t offset;

    template<typename T>
    T& get(void* instance) const {
        return *reinterpret_cast<T*>((char*)instance + offset);
    }
};

六、类型信息结构 Type

cpp复制编辑struct Type {
    std::string name;
    size_t size;
    std::function<void*(void)> creator;
    std::function<void(void*)> deleter;
    std::vector<Field> fields;

    void* create() const { return creator(); }
    void destroy(void* obj) const { deleter(obj); }
};

七、注册表 TypeRegistry

cpp复制编辑class TypeRegistry {
public:
    static TypeRegistry& instance() {
        static TypeRegistry inst;
        return inst;
    }

    void registerType(const std::string& name, const Type& t) {
        types_[name] = t;
    }

    const Type* get(const std::string& name) const {
        auto it = types_.find(name);
        return it != types_.end() ? &it->second : nullptr;
    }

private:
    std::unordered_map<std::string, Type> types_;
};

八、反射注册宏与辅助函数

cpp复制编辑#define BEGIN_REFLECT(T) \
    namespace { \
    struct T##_Reflector { \
        T##_Reflector() { \
            Type t; \
            t.name = #T; \
            t.size = sizeof(T); \
            t.creator = []() -> void* { return new T(); }; \
            t.deleter = [](void* obj) { delete (T*)obj; };

#define REFLECT_FIELD(field, type) \
            t.fields.push_back(Field{#field, #type, offsetof(T, field)});

#define END_REFLECT(T) \
            TypeRegistry::instance().registerType(#T, t); \
        } \
    }; static T##_Reflector global_reflector_##T; }

九、定义一个可反射的类

cpp复制编辑struct Person {
    std::string name;
    int age;
    float height;
};

BEGIN_REFLECT(Person)
    REFLECT_FIELD(name, std::string)
    REFLECT_FIELD(age, int)
    REFLECT_FIELD(height, float)
END_REFLECT(Person)