🚀 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++性能优势的同时提供了强大的运行时反射能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/910369.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/910369.shtml
英文地址,请注明出处:http://en.pswp.cn/news/910369.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

03-D3.js SVG text标签​

Data Visualization D3.js • SuperHiLearn how to create interactive, engaging experiences using HTML, CSS, SVG and Javascript.https://www.superhi.com/catalog/data-visualization-with-d3 text - SVG&#xff1a;可缩放矢量图形 | MDNtext元素定义了一个由文字组成…

Python 使用Gitlab Api

代码 REST API 见自带帮助文档 python 安装python-gitlab pip install --upgrade python-gitlab使用API 参考&#xff1a;https://python-gitlab.readthedocs.io/en/stable/api-usage.html import gitlab# anonymous read-only access for public resources (GitLab.com…

中医体质识别:理论、方法与应用的简要综述

中医体质识别&#xff1a;理论、方法与应用的简要综述 摘要 中医体质识别是中医“治未病”及个性化诊疗的关键环节。本文系统阐述中医体质识别&#xff0c;涵盖理论基础、常见体质类型、识别方法、现代技术应用及临床实践。中医体质理论源远流长&#xff0c;《黄帝内经》奠定…

稀疏表原理及应用场景

1 概述 稀疏表&#xff08;Sparse Table&#xff0c;ST&#xff09;是一种用于高效解决 静态区间查询&#xff08;Range Query&#xff09; 问题的数据结构&#xff0c;主要用于 可重复贡献问题&#xff08;Idempotent Range Queries&#xff09;&#xff0c;例如区间最小值&a…

【深度学习与机器学习的区别】从本质到应用的全景对比

目录 前言 一、三者关系&#xff1a;深度学习是机器学习的子集 1.1 概念关系 1.2 类比理解&#xff1a;动物 vs 哺乳动物 1.3 举个例子更清楚 1.4 为什么“机器学习 ≠ 深度学习”&#xff1f; 1.5 最容易搞混的地方 二、核心区别总览&#xff08;对比表&#xff09; …

Masscan常用命令详解

一、工具介绍 Masscan是一款开源、高速的网络端口扫描工具&#xff0c;设计目标是实现最快的扫描速度。它能够在极短的时间内完成大规模的网络扫描&#xff0c;适用于互联网级别的扫描任务。它采用异步传输和自定义TCP/IP协议栈技术&#xff0c;最快可实现每秒160万数据包的扫…

STM32的内部RC与外部晶振电路

内部RC是“能用”&#xff0c;外部晶振是“用得准”。 一、STM32芯片内部的“晶振电路”是什么&#xff1f; STM32内部确实集成了两个RC&#xff08;电阻-电容&#xff09;振荡器&#xff1a; HSI&#xff08;高速内部振荡器&#xff09;&#xff1a;通常8MHz&#xff0c;精…

为OneCode 开发TRea 开发插件,从环境搭建到生态融合

作为 AI 原生开发环境&#xff0c;TRea 的插件体系支持开发者基于其核心能力&#xff08;如自然语言代码生成、AI 代码分析&#xff09;进行功能扩展。本文以开发一个 "OneCode 组件生成插件" 为例&#xff0c;详解如何通过 TRea 开放接口实现自定义功能&#xff0c;…

Spring JDBC配置与讲解

目录 一、Spring JDBC概述1、Spring JDBC需要配置的依赖2、Spring配置项文件配置 二、Spring JDBC的使用1、Spring JDBC的增加操作2、Spring JDBC的修改操作3、Spring JDBC的删除操作4、Spring JDBC的查询操作 三、Spring JDBC的事务1、xml的形式进行事务2、Transactional注解 …

【AI智能体】Spring AI MCP 服务常用开发模式实战详解

目录 一、前言 二、MCP 介绍 2.1 MCP是什么 2.2 MCP 核心特点 2.3 Spring AI MCP 介绍 2.3.1 Spring AI MCP架构 2.3.2 Spring AI MCP分层说明 2.4 两种模式介绍 三、本地开发SSE模式 3.1 搭建mcp-server 3.1.1 导入工程核心依赖 3.1.2 添加配置文件 3.1.3 提供两个…

OpenStack 入门与实践

一、云计算概述 1.1 云计算的定义与本质 云计算&#xff08;Cloud Computing&#xff09;是一种基于网络的超级计算模式&#xff0c;它能够根据用户的不同需求&#xff0c;动态提供所需的计算资源、存储资源和网络资源等。这种模式就像我们日常生活中使用水电煤气一样&#x…

AntV L7入门教程

以下教程将系统地介绍 AntV L7 的核心 Scene 类用法&#xff0c;涵盖实例化、地图配置、视图操作、图层管理、事件监听及资源销毁等常用 API&#xff0c;并为每个方法给出完整示例代码。所有示例均基于官方 API 文档 ([l7.antv.antgroup.com][1])。 一、安装与引入 # 安装 L7…

【边缘计算】场景

工业互联网 对现场采集的数据进行数据预处理&#xff0c;将现场有用的信息提取出来实时上传给平台&#xff0c;为平台大大减轻了处理的工作量。 汇聚现场数据统一接口上传数据到云端&#xff0c;大大提高系统多样部署的安全性&#xff0c;解决现场数据跨域访问的问题。制造企业…

【FPGA学习】DDS信号发生器设计

目录 一、设计原理与准备​ 1.1 DDS 原理​ 1.2 IP 核学习与准备​&#xff1a;FPGA开发中常用IP核——ROM/RAM/FIFO 2、ROM文件的设置 1.3 开发环境搭建​ 二、DDS 信号发生器设计实现 2.1 系统架构设计​ 2.2 代码编写与模块实现​ 三、测试结果与总结​ 参考文献&…

pyqt 简单条码系统

生产数据管理系统说明 系统概述 这是一个基于PyQt5和pyodbc开发的生产数据管理系统&#xff0c;主要用于管理生产过程中的物料绑定和查询操作。系统提供了上料绑定和下料查询功能&#xff0c;支持与SQL Server数据库交互&#xff0c;实现数据的插入、查询、更新和删除操作。界…

【unitrix】 4.1 类型级加一操作(Add1.rs)

一、原码 这段代码实现了一个类型级的加一操作(Add1 trait)&#xff0c;用于在Rust的类型系统中进行数值加一运算。 //! 加一操作特质实现 / Increment operation trait implementation //! //! 说明&#xff1a; //! 1. Z0、P1,、N1 1&#xff0c;常规计算 //! 2. …

git工作中常用

1.管理本地文件 git init//初始化生成一个本地仓库 git add * //添加到暂存区 git commit–m “message” //提交到本地仓库 2.删除本地分支 git branch -d local_branch_name3.隐藏及解除隐藏 git stashgit stash pop4.远程新建分支&#xff0c;在本地签出时候怎么看到 …

Golang 中接口嵌套的详细说明和使用示例

在 Go 语言中&#xff0c;接口嵌套&#xff08;也称为接口组合&#xff09;是一种强大的特性&#xff0c;它允许你通过组合现有接口来创建新的接口。这种方式遵循了 Go 的组合优于继承的设计哲学。 接口嵌套的基本概念 接口嵌套是指在一个接口中嵌入其他接口&#xff0c;从而…

数智管理学(二十四)

第二章 数智化重塑管理的核心 第三节 动态资源配置与实时优化 在当今数智化浪潮的席卷下&#xff0c;企业管理面临着前所未有的变革与挑战。资源配置作为企业管理的核心环节之一&#xff0c;其方式和效率直接影响着企业的运营成本、生产效率和市场竞争力。传统的静态资源配置…

Redis 各版本差异及性能测试指标对比

Redis 各版本差异及性能测试指标对比 Redis 主要版本差异 Redis 2.x 系列 主要特性&#xff1a; 支持主从复制支持简单的持久化(RDB和AOF)发布/订阅功能事务支持 局限性&#xff1a; 单线程模型集群功能有限 Redis 3.x 系列 重大改进&#xff1a; 引入Redis Cluster(官方…