2026/4/7 12:45:14
网站建设
项目流程
怎么建设58同城网站,做网站没有创意,不备案的网站需要注销吗,怎样做网站信箱一、引言在很多高级语言#xff08;如 C#/Java#xff09;中#xff0c;“反射”是一种内省机制#xff0c;允许程序在运行时查看和操作对象的结构与行为#xff08;如类名、字段、方法等#xff09;。而 C 作为静态语言#xff0c; 默认并不支持强反射机制。尽管 C 提供…一、引言在很多高级语言如 C#/Java中“反射”是一种内省机制允许程序在运行时查看和操作对象的结构与行为如类名、字段、方法等。而 C 作为静态语言默认并不支持强反射机制。尽管 C 提供 RTTI如typeid和dynamic_cast但其功能非常有限并且很多高性能或嵌入式环境都禁用了 RTTI。本文将从零开始实现一个纯 C 的运行时反射系统不依赖 RTTI可实现字段注册、类型名称、对象属性遍历、动态构造等能力。二、反射系统的应用场景场景用途编辑器属性面板展示与绑定脚本接口反射 C 对象给 Lua/Python序列化将对象自动转为 JSON/XML/Binary插件系统不同模块之间的统一字段解析与操作网络通信自动化消息结构注册与生成三、目标功能概览我们的运行时反射系统应具备以下能力注册类型信息类名、字段动态构造对象new 及析构遍历字段获取/设置值查询字段类型、名称、偏移量跨模块兼容性不依赖 RTTI四、核心设计思路设计三个核心类Type表示一个类的信息Field表示类的一个字段属性TypeRegistry集中管理所有注册的类型我们通过宏 模板封装类信息在运行时自动注册。五、字段描述结构 Fieldcpp复制编辑struct Field { std::string name; std::string type; size_t offset; templatetypename T T get(void* instance) const { return *reinterpret_castT*((char*)instance offset); } };六、类型信息结构 Typecpp复制编辑struct Type { std::string name; size_t size; std::functionvoid*(void) creator; std::functionvoid(void*) deleter; std::vectorField fields; void* create() const { return creator(); } void destroy(void* obj) const { deleter(obj); } };七、注册表 TypeRegistrycpp复制编辑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_mapstd::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)十、使用反射 APIcpp复制编辑void demo_reflect() { const Type* t TypeRegistry::instance().get(Person); if (!t) return; void* obj t-create(); for (const Field f : t-fields) { std::cout Field: f.name , Type: f.type std::endl; if (f.name age) { f.getint(obj) 30; } } Person* p (Person*)obj; std::cout Person.age p-age std::endl; t-destroy(obj); }输出结果yaml复制编辑Field: name, Type: std::stringField: age, Type: intField: height, Type: floatPerson.age 30十一、扩展方向建议功能实现方式说明反射方法成员函数可通过std::functionvoid(void*)储存继承关系反射Type 中添加 base_class_name 字段JSON 自动序列化使用字段遍历 std::ostringstream属性读写回调添加 Getter/Setter 函数映射多模块反射DLL用注册表为跨模块插件通信提供基础十二、与 RTTI 的比较特性RTTI (typeid)自定义反射系统获取字段❌✅获取类型名称✅✅动态构造对象❌需手写工厂✅可控字段注册❌✅支持嵌入式/禁 RTTI❌✅十三、实际应用案例1. 自动序列化为 JSONcpp复制编辑std::string to_json(const void* obj, const Type* t) { std::ostringstream oss; oss {; for (size_t i 0; i t-fields.size(); i) { const auto f t-fields[i]; oss \ f.name \:; if (f.type int) oss f.getint(obj); else if (f.type float) oss f.getfloat(obj); else oss \ f.getstd::string(obj) \; if (i t-fields.size() - 1) oss ,; } oss }; return oss.str(); }输出示例json复制编辑{name:Tom,age:30,height:175.5}十四、总结本文实现了一个无 RTTI 的运行时反射系统覆盖字段描述与对象内存偏移类型注册与查找对象动态构造与释放字段遍历与读取设置实战序列化场景应用该机制可轻松嵌入游戏引擎、插件框架、可视化工具中提升系统的模块化与扩展能力。