深度剖析: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++性能優勢的同時提供了強大的運行時反射能力。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處: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(官方…