欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > 深度剖析:RTTI轻量框架实现原理与架构(C++ 17 高级编程)

深度剖析:RTTI轻量框架实现原理与架构(C++ 17 高级编程)

2025/12/14 12:01:09 来源:https://blog.csdn.net/liulilittle/article/details/148826934  浏览:    关键词:深度剖析:RTTI轻量框架实现原理与架构(C++ 17 高级编程)

🚀 C++ RTTI反射系统深度设计文档

🌌 核心架构图

Object基类
RTTI系统
类型注册表
字段元数据
类名->创建函数
类名->RTTI对象
基础类型
容器类型
引用类型
int, float, string等
vector, queue, array等
shared_ptr, unique_ptr等
宏系统
模板元编程

架构说明

  • Object基类:所有反射类的共同基类,提供GetType()接口
  • RTTI系统:核心反射引擎,管理类型元数据
  • 类型注册表:全局类名字典,支持动态创建和类型查找
  • 字段元数据:存储字段类型、偏移量和访问方法

🔄 类型注册流程

用户代码 RTTI宏 RTTI系统 全局注册表 RTTI_S(MyClass) 创建__RTTI__内部类 注册类名->>创建函数 注册类名->>RTTI对象 初始化字段映射表 RTTI_FIELD(myField) 计算字段偏移量 类型推导 标记为BasicType 标记ListType 提取元素类型 标记ReferenceType 提取指向类型 alt [基础类型] [容器类型] [智能指针] 添加字段到映射表 RTTI_E 完成类型注册 用户代码 RTTI宏 RTTI系统 全局注册表

注册流程关键点

  1. 类注册RTTI_S宏创建内部RTTI类并初始化元数据
  2. 字段注册RTTI_FIELD计算字段偏移量并推导类型
  3. 完成注册RTTI_E宏结束注册过程

🧠 内存布局与访问原理

反射访问
obj + offset
偏移量
RTTI::Field
直接内存访问
对象实例
字段x
字段y
容器字段
元素1
元素2
元素3

🧩 关键代码实现:

// 基于偏移量的内存访问
template <typename TValue>
TValue& RTTI::Field::GetValue(Object* obj) noexcept {return *(TValue*)((char*)obj + Offset);
}// 偏移量计算宏
#define RTTI_OFFSET_OF(class, field) \(reinterpret_cast<size_t>(&reinterpret_cast<char&>( \reinterpret_cast<class*>(0)->field)))

内存访问原理

  1. 偏移量计算:在注册时计算字段在类中的内存偏移
  2. 直接内存访问:通过对象指针 + 偏移量直接访问字段内存
  3. 零开销:无虚函数调用,无中间层,直接操作内存

🔍 类型推导系统

vector
queue
array
shared_ptr
unique_ptr
int
float
string
原始类型
容器类型?
具体容器
提取元素类型
智能指针?
提取指向类型
基础类型?
标记BasicType_kInt
标记BasicType_kFloat
标记BasicType_kString
自定义类
查找RTTI信息

🧬 类型推导核心代码:

template <typename T>
struct TypeTraits {static constexpr bool IsContainer = false;static constexpr bool IsPointer = false;// ... 其他类型特征
};// 容器类型特化
template <typename T>
struct TypeTraits<std::vector<T>> {static constexpr bool IsContainer = true;using ElementType = T;static constexpr ListType ContainerType = ListType_kVector;
};// 智能指针特化
template <typename T>
struct TypeTraits<std::shared_ptr<T>> {static constexpr bool IsPointer = true;using PointeeType = T;static constexpr ReferenceType PtrType = ReferenceType_kSharedPointer;
};// 类型推导入口
template <typename T>
Field CreateField(const std::string& name, size_t offset) {if constexpr (TypeTraits<T>::IsContainer) {using Element = typename TypeTraits<T>::ElementType;Field field(name, offset, FieldType::Container);field.ElementType = CreateField<Element>("", 0);return field;}else if constexpr (TypeTraits<T>::IsPointer) {using Pointee = typename TypeTraits<T>::PointeeType;Field field(name, offset, FieldType::Reference);field.PointeeType = CreateField<Pointee>("", 0);return field;}// ... 其他类型处理
}

类型推导特点

  1. 编译期推导:使用模板特化和constexpr在编译期完成类型分析
  2. 递归处理:支持嵌套类型如vector<shared_ptr<GameObject>>
  3. 类型特征萃取:通过TypeTraits提取类型特征信息

📦 容器操作原理

queue访问
vector访问
&back
GetLastValuePointer
data + index
GetValuePointer
容器操作
vector
queue
array
随机访问
队列操作
静态访问

🧪 容器访问示例:

// 获取容器元素指针
void* RTTI::Field::GetElementPointer(Object* obj, int index) {switch (ContainerType) {case ListType_kVector:auto& vec = *reinterpret_cast<std::vector<char>*>((char*)obj + Offset);return vec.data() + index * ElementType.Size;case ListType_kQueue:auto& que = *reinterpret_cast<std::queue<char>*>((char*)obj + Offset);// 特殊处理队列访问return AccessQueueElement(que, index);// 其他容器类型处理}
}// 修改vector元素
template <typename TValue>
bool RTTI::Field::SetValue(Object* obj, int index, const TValue& value) {if (ListType == ListType_kVector) {auto& vec = GetValue<std::vector<TValue>>(obj);if (index >= 0 && index < vec.size()) {vec[index] = value;return true;}}return false; // 边界检查失败
}

容器操作关键

  1. 类型安全访问:通过模板确保类型正确性
  2. 边界检查:防止越界访问
  3. 零拷贝:直接操作容器内存,避免不必要的拷贝

🧲 智能指针支持

指向元素类型
1
1
包含
1
1
Field
+ReferenceType
+Type*
GameObject
+shared_ptr<GameObject> child
RTTI

🔌 智能指针操作:

// 获取智能指针指向的对象
template <typename T>
T* RTTI::Field::GetPointedObject(Object* obj) {if (ReferenceType == ReferenceType_kSharedPointer) {auto& ptr = GetValue<std::shared_ptr<T>>(obj);return ptr.get();}else if (ReferenceType == ReferenceType_kUniquePointer) {auto& ptr = GetValue<std::unique_ptr<T>>(obj);return ptr.get();}return nullptr;
}// 重置智能指针
template <typename T>
void RTTI::Field::ResetPointer(Object* obj, T* newPtr) {if (ReferenceType == ReferenceType_kSharedPointer) {auto& ptr = GetValue<std::shared_ptr<T>>(obj);ptr.reset(newPtr);}else if (ReferenceType == ReferenceType_kUniquePointer) {auto& ptr = GetValue<std::unique_ptr<T>>(obj);ptr.reset(newPtr);}
}

智能指针支持特点

  1. 安全访问:通过get()方法获取原始指针,避免直接暴露
  2. 生命周期管理:支持reset等操作管理对象生命周期
  3. 空指针检测:自动处理空指针情况

⚙️ 宏系统实现原理

RTTI_S
定义内部类
注册创建函数
初始化字段表
RTTI_FIELD
计算偏移
类型推导
添加字段
RTTI_E
完成注册

🔬 宏展开示例:

// 原始代码
RTTI_S(GameObject)
RTTI_FIELD(position)
RTTI_E// 展开后
class __RTTI__GameObject : public RTTI {
public:static __RTTI__GameObject r;__RTTI__GameObject() {GlobalRegistry::Register("GameObject", []{ return new GameObject(); },this);// 注册字段RegisterField("position", offsetof(GameObject, position),TypeTraits<Vector3>::GetTypeInfo());}
};
__RTTI__GameObject __RTTI__GameObject::r;// 在GameObject类中添加
virtual RTTI* GetType() const override {return &__RTTI__GameObject::r;
}

宏系统优势

  1. 简化注册:用户只需简单宏调用即可完成复杂注册
  2. 自动生成代码:在预处理阶段生成必要的RTTI代码
  3. 隔离复杂性:用户无需了解底层实现细节

⚡ 性能优化设计

性能优化
直接内存访问
编译期类型推导
O1类型查找
零拷贝容器操作
无虚函数开销
无运行时类型检查
哈希表查找

性能优化措施

  1. 内存访问优化

    // 直接内存访问,无函数调用开销
    #define DIRECT_ACCESS(ptr, offset) \(*reinterpret_cast<std::decay_t<decltype(ptr)>*>( \reinterpret_cast<char*>(ptr) + offset))
    
  2. 编译期类型解析

    template <typename T>
    constexpr FieldType DeduceFieldType() {if constexpr (std::is_integral_v<T>) return FieldType::Int;else if constexpr (std::is_floating_point_v<T>) return FieldType::Float;// ... 其他类型
    }
    
  3. 快速注册表查找

    class GlobalRegistry {
    private:static std::unordered_map<std::string, RTTI*> typeMap;static std::unordered_map<std::string, CreatorFunc> creatorMap;public:template <typename T>static void Register(const std::string& name) {typeMap[name] = T::GetStaticType();creatorMap[name] = []{ return new T(); };}
    };
    

🧪 完整操作示例

应用程序 RTTI系统 游戏对象 Field New("GameObject") 创建实例 返回对象指针 obj->>GetType() 返回RTTI对象 GetAllFields() 返回字段列表 GetField("position") 返回Field对象 GetValue<Vector3>(obj) 返回position引用 SetValue(obj, Vector3(1,2,3)) 修改内存值 应用程序 RTTI系统 游戏对象 Field

典型使用场景

// 动态创建对象
GameObject* obj = RTTI::New("GameObject");// 获取类型信息
RTTI* type = obj->GetType();// 遍历所有字段
for (auto& field : type->GetFields()) {std::cout << "Field: " << field.Name << " Type: " << field.TypeName();
}// 修改字段值
if (auto* posField = type->GetField("position")) {Vector3 newPos(10, 20, 30);posField->SetValue(obj, newPos);
}

🔧 框架扩展机制

扩展点
新容器支持
自定义类型
序列化
脚本绑定
特化模板
继承Object
反射遍历
绑定字段
添加容器检测
实现访问方法

🧩 扩展示例:

// 添加自定义容器支持
template <typename T>
struct is_custom_container : std::false_type {};template <typename T>
struct is_custom_container<MyVector<T>> : std::true_type {};// 在类型推导中添加处理分支
template <typename T>
Field CreateField(const std::string& name, size_t offset) {if constexpr (is_custom_container<T>::value) {Field field(name, offset, FieldType::CustomContainer);// 实现自定义访问方法field.GetElement = [](void* container, int index) {return &static_cast<MyVector<char>*>(container)->GetElement(index);};return field;}// ... 其他类型
}// 序列化扩展
void Serialize(Object* obj, std::ostream& out) {RTTI* type = obj->GetType();for (auto& field : type->GetFields()) {out << field.Name << ": ";if (field.IsBasicType()) {// 基础类型序列化}else if (field.IsContainer()) {// 容器序列化}}
}

扩展能力

  1. 新容器支持:通过模板特化添加新容器类型
  2. 序列化:基于反射自动序列化/反序列化
  3. 脚本绑定:自动生成脚本语言绑定代码
  4. 编辑器集成:自动生成属性面板

📊 类型系统总览

支持类型
基础类型
容器类型
引用/指针类型
值类型

详细类型支持矩阵

类型类别具体类型C++示例RTTI表示
基础类型整数int, int32_tBasicType_kInt
浮点数float, doubleBasicType_kFloat
字符串std::stringBasicType_kString
布尔boolBasicType_kBoolean
容器类型动态数组std::vectorListType_kVector
队列std::queueListType_kQueue
静态数组std::arrayListType_kStatic
集合std::setListType_kSet
指针类型原始指针GameObject*ReferenceType_kPointer
共享指针std::shared_ptrReferenceType_kSharedPointer
唯一指针std::unique_ptrReferenceType_kUniquePointer
值类型自定义类Vector3FieldType_Custom

🏆 框架优势总结

  1. 高性能设计

    • 直接内存访问(零抽象开销)
    • 编译期类型解析(零运行时成本)
    • 哈希表快速查找(O(1)复杂度)
  2. 强大类型支持

    // 支持复杂嵌套类型
    class Scene {std::vector<std::shared_ptr<GameObject>> objects;std::map<int, std::array<float, 4>> colorPalette;RTTI_FIELD(objects);RTTI_FIELD(colorPalette);
    };
    
  3. 安全保证

    • 类型安全访问
    • 容器边界检查
    • 空指针检测
  4. 可扩展架构

    // 轻松添加新功能
    RTTI_REGISTER_EXTENSION(Serialization, {// 序列化实现
    });
    

🧩 RTTI 轻量框架运行库实现

  1. DEMO
#include "RTTI.h"
#include "Object.h"struct Vector3 : public Object {float x, y, z;Vector3(float x = 0, float y = 0, float z = 0) : x(x), y(y), z(z) {}RTTI_S(Vector3);RTTI_FIELD(x);RTTI_FIELD(y);RTTI_FIELD(z);RTTI_E;
};struct GameObject : public Object {std::string name;Vector3 position;std::shared_ptr<GameObject> child;std::vector<int> scores;std::queue<std::string> messages;GameObject() {scores = { 90, 85, 95 };messages.push("Hello");messages.push("World");}RTTI_S(GameObject);RTTI_FIELD(name);RTTI_FIELD(position);RTTI_FIELD(child);RTTI_FIELD(scores);RTTI_FIELD(messages);RTTI_E;
};static void InitMetadata() {RTTI_I(Vector3);RTTI_I(GameObject);
}std::string GetTypeName(const RTTI::Field* field) {// 优先处理容器元素类型if (field->ListType != RTTI::ListType_kNull && field->Type) {return field->Type->GetName();}// 处理引用类型if (field->ReferenceType != RTTI::ReferenceType_kNull && field->Type) {return field->Type->GetName();}// 基本类型处理switch (field->BaiscType) {case RTTI::BasicType_kInt: return "int";case RTTI::BasicType_kUInt: return "uint";case RTTI::BasicType_kFloat: return "float";case RTTI::BasicType_kString: return "string";case RTTI::BasicType_kClass:return field->Type ? field->Type->GetName() : "unknown_class";default: return "unknown";}
}void PrintFieldInfo(RTTI::Field* field) {std::cout << "  " << field->Name << " [";// 打印容器类型if (field->ListType != RTTI::ListType_kNull) {switch (field->ListType) {case RTTI::ListType_kVector: std::cout << "vector<"; break;case RTTI::ListType_kQueue: std::cout << "queue<"; break;case RTTI::ListType_kStatic: std::cout << "array<"; break;default: std::cout << "container<";}std::cout << GetTypeName(field);std::cout << ">";if (field->ListType == RTTI::ListType_kStatic) {std::cout << ", size=" << field->ArraySize;}}// 打印引用类型else if (field->ReferenceType != RTTI::ReferenceType_kNull) {switch (field->ReferenceType) {case RTTI::ReferenceType_kSharedPointer:std::cout << "shared_ptr<"; break;case RTTI::ReferenceType_kUniquePointer:std::cout << "unique_ptr<"; break;default: std::cout << "ref<";}std::cout << GetTypeName(field) << ">";}// 打印基本类型else {std::cout << GetTypeName(field);}std::cout << "]\n";
}int main() {InitMetadata();// 动态创建对象GameObject* obj = (GameObject*)RTTI::New("GameObject");obj->name = "Player1";// 获取类型信息RTTI* type = obj->GetType();std::cout << "Type: " << type->GetName() << "\n";// 遍历所有字段std::cout << "\nFields Info:\n";for (auto& [name, field] : type->GetAllFields()) {PrintFieldInfo(const_cast<RTTI::Field*>(&field));}// 反射访问基本类型RTTI::Field* nameField = type->GetField("name");std::string nameValue = nameField->GetValue<std::string>(obj);std::cout << "\nName: " << nameValue << "\n";// 反射访问嵌套对象RTTI::Field* posField = type->GetField("position");Vector3& pos = posField->GetValue<Vector3>(obj);std::cout << "Position: (" << pos.x << ", " << pos.y << ", " << pos.z << ")\n";// 修改容器字段 - vectorRTTI::Field* scoresField = type->GetField("scores");scoresField->SetValue(obj, 1, 100); // 修改第二个元素// 访问容器字段 - queueRTTI::Field* msgField = type->GetField("messages");std::string* lastMsg = nullptr;if (msgField->GetLastValuePointer(obj, &lastMsg)) {*lastMsg = "Modified!"; // 修改队列尾部std::cout << "Last message: " << *lastMsg << "\n";}// 反射创建智能指针对象RTTI::Field* childField = type->GetField("child");GameObject* childObj = (GameObject*)RTTI::New("GameObject");childObj->name = "Child";childField->SetValue2(obj, std::shared_ptr<GameObject>(childObj));// 获取智能指针字段std::shared_ptr<GameObject>& childRef =childField->GetValue<std::shared_ptr<GameObject>>(obj);std::cout << "Child name: " << childRef->name << "\n";delete obj;return 0;
}
  1. Object.h
#pragma once#include <unordered_map>
#include <iostream>#include <list>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <array>
#include <mutex>
#include <vector>
#include <functional>
#include <type_traits>#ifndef offset_of
#define offset_of(type, member) ((size_t)&reinterpret_cast<char const volatile&>((((type*)0)->member)))
#endif#ifndef container_of
#define container_of(ptr, type, member) ((type*)((char*)static_cast<const decltype(((type*)0)->member)*>(ptr) - offset_of(type, member)))
#endif#ifndef type_of
#define type_of(type) (type::TypeOf())
#endifclass Object {friend class RTTI;public:virtual RTTI*               GetType() noexcept = 0;virtual int                 GetHashCode() noexcept { return (int)std::hash<uint64_t>()(reinterpret_cast<uint64_t>(this));}
};template <typename T>
constexpr T& constant_of(const T& v) noexcept {return const_cast<T&>(v);
}
  1. RTTI.h
#pragma once#include "Object.h"#define RTTI_S(clazz) \public: static std::string GetClassName() noexcept { return #clazz; } \private: class __RTTI__ : public RTTI { \typedef clazz _Ty; \public: \static __RTTI__& c() noexcept { \static __RTTI__ r; \return r; \} \virtual std::string GetName() const noexcept override { return #clazz; } \__RTTI__() noexcept { \__rtti_ptrs[#clazz] = this; \__rtti_news[#clazz] = []() noexcept -> Object* { return new clazz(); };  \

#define RTTI_E \} \}; \public: static RTTI* TypeOf() noexcept { return &__RTTI__::c(); } \public: virtual RTTI* GetType() noexcept override { return &__RTTI__::c(); }#define RTTI_FIELD(var) \__rtti_fields[#var] = __RTTI_IMPL__::__RTTI_IMPL_FIELD_CLASS__::RTTI_GetField_0<std::remove_reference<decltype(((_Ty*)0)->var)>::type>(#var, offset_of(_Ty, var));#define RTTI_I(clazz) type_of(clazz);class Object;class RTTI {
protected:typedef Object* (*NewObjectFx)();static std::unordered_map<std::string, NewObjectFx> __rtti_news;static std::unordered_map<std::string, RTTI*>       __rtti_ptrs;public:enum kBasicType {BasicType_kClass,BasicType_kString,BasicType_kChar,BasicType_kSByte,BasicType_kByte,BasicType_kShort,BasicType_kUShort,BasicType_kInt,BasicType_kUInt,BasicType_kLong,BasicType_kULong,BasicType_kBoolean,BasicType_kFloat,BasicType_kDouble,BasicType_kDecimal,};enum kReferenceType {ReferenceType_kNull,ReferenceType_kPointer,ReferenceType_kReference,ReferenceType_kWeakPointer,ReferenceType_kUniquePointer,ReferenceType_kSharedPointer,};enum kListType {ListType_kNull,ListType_kArray,ListType_kList,ListType_kVector,ListType_kStack,ListType_kQueue,ListType_kStatic,ListType_kSet,ListType_kMultiSet,};class Field final {public:const std::string                               Name;const int                                       Offset              = 0;const RTTI*                                     Type                = NULL;const bool                                      Constant            = false;const kBasicType                                BaiscType           = BasicType_kClass;const kReferenceType                            ReferenceType       = ReferenceType_kNull;const kListType                                 ListType            = ListType_kNull;const int                                       SizeOf              = 0;const int                                       ArraySize           = 0;public:const Field&                                    operator=(const Field& reft) const noexcept {Field& left = const_cast<Field&>(*this);constant_of(left.Name) = reft.Name;constant_of(left.Offset) = reft.Offset;constant_of(left.Type) = reft.Type;constant_of(left.Constant) = reft.Constant;constant_of(left.BaiscType) = reft.BaiscType;constant_of(left.ListType) = reft.ListType;constant_of(left.SizeOf) = reft.SizeOf;constant_of(left.ArraySize) = reft.ArraySize;constant_of(left.ReferenceType) = reft.ReferenceType;return left;}template <typename TValue>TValue&                                         GetValue(Object* obj) noexcept;template <typename TValue>bool                                            GetValue(Object* obj, int index, TValue& out) noexcept;template <typename TValue>bool                                            SetValue(Object* obj, int index, const TValue& value) noexcept;template <typename TValue>bool                                            GetValuePointer(Object* obj, int index, TValue** out) noexcept;template <typename TValue>TValue&                                         SetValue(Object* obj, const TValue& value) noexcept;template <typename TValue>TValue&                                         SetValue2(Object* obj, TValue&& value) noexcept;template <typename TValue>bool                                            GetFirstValuePointer(Object* obj, TValue** out) noexcept;template <typename TValue>bool                                            GetLastValuePointer(Object* obj, TValue** out) noexcept;template <typename TValue>bool                                            GetFirstValue(Object* obj, TValue& out) noexcept;template <typename TValue>bool                                            GetLastValue(Object* obj, TValue& out) noexcept;private:template <typename TList, typename TValue>bool                                            GetFirstValuePointer2(Object* obj, TValue** out) noexcept;template <typename TList, typename TValue>bool                                            GetLastValuePointer2(Object* obj, TValue** out) noexcept;};Field*                                              GetField(const std::string& method) noexcept;const std::unordered_map<std::string, RTTI::Field>& GetAllFields() noexcept { return __rtti_fields; }virtual std::string                                 GetName() const noexcept = 0;static RTTI*                                        GetType(const std::string& class_name) noexcept;Object*                                             New() noexcept;static Object*                                      New(const std::string& class_name) noexcept;protected:std::unordered_map<std::string, RTTI::Field>        __rtti_fields;
};namespace __RTTI_IMPL__ {class __RTTI_IMPL_FIELD_CLASS__{template <typename T>struct HAS_MEMBER_TYPE_OF_FUNCTION final {private:template <typename U>static auto                                 SFINAE_TEST(T*) noexcept -> decltype(std::declval<U>().GetType(), std::true_type());template <typename U>static std::false_type                      SFINAE_TEST(...) noexcept;public:static constexpr bool                       value = decltype(SFINAE_TEST<T>(NULL))::value;};template <typename T>struct is_shared_ptr : std::false_type {};template <typename T>struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};template <typename T>struct is_weak_ptr : std::false_type {};template <typename T>struct is_weak_ptr<std::weak_ptr<T>> : std::true_type {};template <typename T>struct is_unique_ptr : std::false_type {};template <typename T>struct is_unique_ptr<std::unique_ptr<T>> : std::true_type {};template <typename T>struct is_vector : std::false_type {};template <typename T>struct is_vector<std::vector<T>> : std::true_type {};template <typename T>struct is_list : std::false_type {};template <typename T>struct is_list<std::list<T>> : std::true_type {};template <typename T>struct is_stack : std::false_type {};template <typename T>struct is_stack<std::stack<T>> : std::true_type {};template <typename T>struct is_queue : std::false_type {};template <typename T>struct is_queue<std::queue<T>> : std::true_type {};template <typename T>struct is_set : std::false_type {};template <typename T>struct is_set<std::set<T>> : std::true_type {};template <typename T>struct is_multiset : std::false_type {};template <typename T>struct is_multiset<std::multiset<T>> : std::true_type {};template <typename T>struct is_array : std::false_type {};template <typename T, std::size_t N>struct is_array<std::array<T, N>> : std::true_type {typedef T type;static constexpr std::size_t length = N;};template <typename T>struct is_static_array : std::false_type {};template <typename T, std::size_t N>struct is_static_array<T[N]> : std::true_type {static constexpr std::size_t length = N;};public:template <typename _Ty>static RTTI*                                    RTTI_GetType() noexcept {if constexpr (std::is_base_of<Object, _Ty>::value && HAS_MEMBER_TYPE_OF_FUNCTION<_Ty>::value) {RTTI* type = RTTI::GetType(_Ty::GetClassName());if (NULL != type) {return type;}return _Ty::TypeOf();}else {return NULL;}}template <typename _Ty>static RTTI::Field                              RTTI_GetField_0(const std::string& name, int offset) noexcept {using _Ty2 = typename std::remove_const<_Ty>::type;return RTTI_GetField_1<_Ty2>(name, offset, std::is_const<_Ty>::value);}template <typename _Ty>static RTTI::Field                              RTTI_GetField_1(const std::string& name, int offset, bool constant) noexcept {if constexpr (is_vector<_Ty>::value) {using _Ty2 = typename std::remove_reference<decltype(*((_Ty*)0)->begin())>::type;return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kVector);}else if constexpr (is_static_array<_Ty>::value) { /* std::is_array<_Ty>::value */using _Ty2 = typename std::remove_reference<decltype(*(*(_Ty*)0))>::type;return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kStatic, is_static_array<_Ty>::length);}else if constexpr (is_array<_Ty>::value) {using _Ty2 = typename std::remove_reference<typename is_array<_Ty>::type>::type;return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kArray, is_array<_Ty>::length);}else if constexpr (is_list<_Ty>::value) {using _Ty2 = typename std::remove_reference<decltype(*((_Ty*)0)->begin())>::type;return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kList);}else if constexpr (is_set<_Ty>::value) {using _Ty2 = typename std::remove_reference<decltype(*((_Ty*)0)->begin())>::type;return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kSet);}else if constexpr (is_multiset<_Ty>::value) {using _Ty2 = typename std::remove_reference<decltype(*((_Ty*)0)->begin())>::type;return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kMultiSet);}else if constexpr (is_stack<_Ty>::value) {using _Ty1 = decltype(((_Ty*)0)->top());using _Ty2 = typename std::remove_const<typename std::remove_reference<_Ty1>::type>::type;return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kStack);}else if constexpr (is_queue<_Ty>::value) {using _Ty1 = decltype(((_Ty*)0)->front());using _Ty2 = typename std::remove_const<typename std::remove_reference<_Ty1>::type>::type;return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kQueue);}else {return RTTI_GetField_2<_Ty>(name, offset, constant, RTTI::ListType_kNull);}}template <typename _Ty>static RTTI::Field                              RTTI_GetField_2(const std::string& name, int offset, bool constant, RTTI::kListType list_type, int array_size = 0) noexcept {RTTI::Field field{ name, offset, NULL, constant, RTTI::BasicType_kClass, RTTI::ReferenceType_kNull, list_type, sizeof(_Ty), array_size };RTTI::kBasicType& basic_type = constant_of(field.BaiscType);if constexpr (std::is_same<_Ty, int32_t>::value || std::is_same<_Ty, int>::value || std::is_same<_Ty, long>::value) {basic_type = RTTI::BasicType_kInt;}else if constexpr (std::is_same<_Ty, uint32_t>::value || std::is_same<_Ty, unsigned int>::value || std::is_same<_Ty, unsigned long>::value) {basic_type = RTTI::BasicType_kUInt;}else if constexpr (std::is_same<_Ty, int64_t>::value || std::is_same<_Ty, long long>::value || std::is_same<_Ty, long long int>::value) {basic_type = RTTI::BasicType_kLong;}else if constexpr (std::is_same<_Ty, uint64_t>::value || std::is_same<_Ty, unsigned long long>::value || std::is_same<_Ty, unsigned long long int>::value) {basic_type = RTTI::BasicType_kULong;}else if constexpr (std::is_same<_Ty, double>::value || std::is_same<_Ty, double_t>::value) {basic_type = RTTI::BasicType_kDouble;}else if constexpr (std::is_same<_Ty, long double>::value) {basic_type = RTTI::BasicType_kDecimal;}else if constexpr (std::is_same<_Ty, bool>::value) {basic_type = RTTI::BasicType_kBoolean;}else if constexpr (std::is_same<_Ty, short>::value || std::is_same<_Ty, int16_t>::value) {basic_type = RTTI::BasicType_kSort;}else if constexpr (std::is_same<_Ty, unsigned short>::value || std::is_same<_Ty, uint16_t>::value) {basic_type = RTTI::BasicType_kUSort;}else if constexpr (std::is_same<_Ty, int8_t>::value) {basic_type = RTTI::BasicType_kSByte;}else if constexpr (std::is_same<_Ty, uint8_t>::value) {basic_type = RTTI::BasicType_kByte;}else if constexpr (std::is_same<_Ty, char>::value) {basic_type = RTTI::BasicType_kChar;}else if constexpr (std::is_same<_Ty, std::string>::value) {basic_type = RTTI::BasicType_kString;}else if constexpr (std::is_pointer<_Ty>::value) {using _Ty2 = typename std::remove_pointer<_Ty>::type;constant_of(field.ReferenceType) = RTTI::ReferenceType_kPointer;constant_of(field.Type) = RTTI_GetType<_Ty2>();constant_of(field.SizeOf) = sizeof(_Ty2);}else if constexpr (is_weak_ptr<_Ty>::value) {using _Ty2 = typename std::remove_pointer<typename _Ty::element_type>;constant_of(field.ReferenceType) = RTTI::ReferenceType_kWeakPointer;constant_of(field.Type) = RTTI_GetType<_Ty2>();constant_of(field.SizeOf) = sizeof(_Ty2);}else if constexpr (is_shared_ptr<_Ty>::value) {using _Ty2 = typename std::remove_pointer<decltype(((_Ty*)0)->get())>::type;constant_of(field.ReferenceType) = RTTI::ReferenceType_kSharedPointer;constant_of(field.Type) = RTTI_GetType<_Ty2>();constant_of(field.SizeOf) = sizeof(_Ty2);}else if constexpr (is_unique_ptr<_Ty>::value) {using _Ty2 = typename std::remove_pointer<decltype(((_Ty*)0)->get())>::type;constant_of(field.ReferenceType) = RTTI::ReferenceType_kUniquePointer;constant_of(field.Type) = RTTI_GetType<_Ty2>();constant_of(field.SizeOf) = sizeof(_Ty2);}else if constexpr (std::is_reference<_Ty>::value) {using _Ty2 = typename std::remove_reference<_Ty>::type;constant_of(field.ReferenceType) = RTTI::ReferenceType_kReference;constant_of(field.Type) = RTTI_GetType<_Ty2>();constant_of(field.SizeOf) = sizeof(_Ty2);}else {constant_of(field.Type) = RTTI_GetType<_Ty>();}return field;}};
}template <typename TValue>
TValue& RTTI::Field::GetValue(Object* obj) noexcept {return *(TValue*)((char*)obj + Offset);
}template <typename TValue>
TValue& RTTI::Field::SetValue(Object* obj, const TValue& value) noexcept {TValue& data = *(TValue*)((char*)obj + Offset);data = value;return data;
}template <typename TValue>
TValue& RTTI::Field::SetValue2(Object* obj, TValue&& value) noexcept {TValue& data = *(TValue*)((char*)obj + Offset);data = value;return data;
}template <typename TValue>
bool RTTI::Field::GetValue(Object* obj, int index, TValue& out) noexcept {TValue* ppv{ NULL };if (!GetValuePointer(obj, index, &ppv)) {return false;}out = *ppv;return true;
}template <typename TValue>
bool RTTI::Field::GetValuePointer(Object* obj, int index, TValue** out) noexcept {if (NULL == out || index < 0) {return false;}else if (ListType == ListType_kStatic || ListType == ListType_kArray) {if (index >= ArraySize) {return false;}TValue& data_ref = GetValue<TValue>(obj);TValue* data_ptr = std::addressof(data_ref);*out = data_ptr + index;return true;}else if (ListType == ListType_kVector) {using _Ty2 = std::vector<TValue>;_Ty2& vc = GetValue<_Ty2>(obj);if (index >= (int)vc.size()) {return false;}*out = vc.data() + index;return true;}else {return false;}
}template <typename TValue>
bool RTTI::Field::SetValue(Object* obj, int index, const TValue& value) noexcept {TValue* ppv{ NULL };if (!GetValuePointer(obj, index, &ppv)) {return false;}*ppv = value;return true;
}template <typename TList, typename TValue>
bool RTTI::Field::GetFirstValuePointer2(Object* obj, TValue** out) noexcept {TList& list = GetValue<TList>(obj);auto tail = list.begin();auto endl = list.end();if (tail == endl) {return false;}auto& ref = *tail;*out = (TValue*)std::addressof(ref);return true;
}template <typename TList, typename TValue>
bool RTTI::Field::GetLastValuePointer2(Object* obj, TValue** out) noexcept {TList& list = GetValue<TList>(obj);auto tail = list.rbegin();auto endl = list.rend();if (tail == endl) {return false;}auto& ref = *tail;*out = (TValue*)std::addressof(ref);return true;
}template <typename TValue>
bool RTTI::Field::GetFirstValuePointer(Object* obj, TValue** out) noexcept {if (NULL == out) {return false;}else if (ListType == ListType_kStatic || ListType == ListType_kArray) {if (ArraySize < 1) {return false;}TValue& data_ref = GetValue<TValue>(obj);*out = std::addressof(data_ref);return true;}else if (ListType == ListType_kVector) {using _Ty2 = std::vector<TValue>;_Ty2& vc = GetValue<_Ty2>(obj);if (vc.empty()) {return false;}*out = vc.data();return true;}else if (ListType == ListType_kList) {using _Ty2 = std::list<TValue>;return GetFirstValuePointer2<_Ty2>(obj, out);}else if (ListType == ListType_kSet) {using _Ty2 = std::set<TValue>;return GetFirstValuePointer2<_Ty2>(obj, out);}else if (ListType == ListType_kMultiSet) {using _Ty2 = std::multiset<TValue>;return GetFirstValuePointer2<_Ty2>(obj, out);}else if (ListType == ListType_kStack) {using _Ty2 = std::stack<TValue>;_Ty2& stack = GetValue<_Ty2>(obj);if (stack.empty()) {return false;}*out = std::addressof(stack.top());return true;}else if (ListType == ListType_kQueue) {using _Ty2 = std::queue<TValue>;_Ty2& queue = GetValue<_Ty2>(obj);if (queue.empty()) {return false;}*out = std::addressof(queue.front());return true;}else {return false;}
}template <typename TValue>
bool RTTI::Field::GetLastValuePointer(Object* obj, TValue** out) noexcept {if (NULL == out) {return false;}else if (ListType == ListType_kStatic || ListType == ListType_kArray) {if (ArraySize < 1) {return false;}TValue& data_ref = GetValue<TValue>(obj);*out = std::addressof(data_ref) + (ArraySize - 1);return true;}else if (ListType == ListType_kVector) {using _Ty2 = std::vector<TValue>;_Ty2& vc = GetValue<_Ty2>(obj);if (vc.empty()) {return false;}*out = std::addressof(*vc.rbegin());return true;}else if (ListType == ListType_kList) {using _Ty2 = std::list<TValue>;return GetLastValuePointer2<_Ty2>(obj, out);}else if (ListType == ListType_kSet) {using _Ty2 = std::set<TValue>;return GetLastValuePointer2<_Ty2>(obj, out);}else if (ListType == ListType_kMultiSet) {using _Ty2 = std::multiset<TValue>;return GetLastValuePointer2<_Ty2>(obj, out);}else if (ListType == ListType_kStack) {using _Ty2 = std::stack<TValue>;_Ty2& stack = GetValue<_Ty2>(obj);std::size_t stack_size = stack.size();if (stack_size != 1) {return false;}*out = std::addressof(stack.top());return true;}else if (ListType == ListType_kQueue) {using _Ty2 = std::queue<TValue>;_Ty2& queue = GetValue<_Ty2>(obj);if (queue.empty()) {return false;}*out = std::addressof(queue.back());return true;}else {return false;}
}template <typename TValue>
bool RTTI::Field::GetFirstValue(Object* obj, TValue& out) noexcept {TValue* ppv{ NULL };if (!GetFirstValuePointer(obj, &ppv)) {return false;}out = *ppv;return true;
}template <typename TValue>
bool RTTI::Field::GetLastValue(Object* obj, TValue& out) noexcept {TValue* ppv{ NULL };if (!GetLastValuePointer(obj, &ppv)) {return false;}out = *ppv;return true;
}
  1. RTTI.cpp
#include "RTTI.h"std::unordered_map<std::string, RTTI::NewObjectFx> RTTI::__rtti_news;
std::unordered_map<std::string, RTTI*> RTTI::__rtti_ptrs;Object* RTTI::New(const std::string& class_name) noexcept {if (class_name.empty()) {return NULL;}auto tail = __rtti_news.find(class_name);auto endl = __rtti_news.end();if (tail == endl) {return NULL;}NewObjectFx f = tail->second;return f();
}RTTI* RTTI::GetType(const std::string& class_name) noexcept {if (class_name.empty()) {return NULL;}auto tail = __rtti_ptrs.find(class_name);auto endl = __rtti_ptrs.end();if (tail == endl) {return NULL;}return tail->second;
}Object* RTTI::New() noexcept  {std::string class_name = GetName();return New(class_name);
}RTTI::Field* RTTI::GetField(const std::string& method) noexcept {if (method.empty()) {return NULL;}auto tail = __rtti_fields.find(method);auto endl = __rtti_fields.end();if (tail == endl) {return NULL;}return &tail->second;
}

本反射系统通过创新的内存访问机制和编译期类型推导,在保持C++性能优势的同时提供了强大的运行时反射能力。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词