🚀 C++ RTTI反射系统深度设计文档
🌌 核心架构图
架构说明:
Object基类:所有反射类的共同基类,提供GetType()接口RTTI系统:核心反射引擎,管理类型元数据类型注册表:全局类名字典,支持动态创建和类型查找字段元数据:存储字段类型、偏移量和访问方法
🔄 类型注册流程
注册流程关键点:
类注册:RTTI_S宏创建内部RTTI类并初始化元数据字段注册:RTTI_FIELD计算字段偏移量并推导类型完成注册:RTTI_E宏结束注册过程
🧠 内存布局与访问原理
🧩 关键代码实现:
// 基于偏移量的内存访问
template
TValue& RTTI::Field::GetValue(Object* obj) noexcept {
return *(TValue*)((char*)obj + Offset);
}
// 偏移量计算宏
#define RTTI_OFFSET_OF(class, field) \
(reinterpret_cast
reinterpret_cast
内存访问原理:
偏移量计算:在注册时计算字段在类中的内存偏移直接内存访问:通过对象指针 + 偏移量直接访问字段内存零开销:无虚函数调用,无中间层,直接操作内存
🔍 类型推导系统
🧬 类型推导核心代码:
template
struct TypeTraits {
static constexpr bool IsContainer = false;
static constexpr bool IsPointer = false;
// ... 其他类型特征
};
// 容器类型特化
template
struct TypeTraits
static constexpr bool IsContainer = true;
using ElementType = T;
static constexpr ListType ContainerType = ListType_kVector;
};
// 智能指针特化
template
struct TypeTraits
static constexpr bool IsPointer = true;
using PointeeType = T;
static constexpr ReferenceType PtrType = ReferenceType_kSharedPointer;
};
// 类型推导入口
template
Field CreateField(const std::string& name, size_t offset) {
if constexpr (TypeTraits
using Element = typename TypeTraits
Field field(name, offset, FieldType::Container);
field.ElementType = CreateField
return field;
}
else if constexpr (TypeTraits
using Pointee = typename TypeTraits
Field field(name, offset, FieldType::Reference);
field.PointeeType = CreateField
return field;
}
// ... 其他类型处理
}
类型推导特点:
编译期推导:使用模板特化和constexpr在编译期完成类型分析递归处理:支持嵌套类型如vector
📦 容器操作原理
🧪 容器访问示例:
// 获取容器元素指针
void* RTTI::Field::GetElementPointer(Object* obj, int index) {
switch (ContainerType) {
case ListType_kVector:
auto& vec = *reinterpret_cast
(char*)obj + Offset);
return vec.data() + index * ElementType.Size;
case ListType_kQueue:
auto& que = *reinterpret_cast
(char*)obj + Offset);
// 特殊处理队列访问
return AccessQueueElement(que, index);
// 其他容器类型处理
}
}
// 修改vector元素
template
bool RTTI::Field::SetValue(Object* obj, int index, const TValue& value) {
if (ListType == ListType_kVector) {
auto& vec = GetValue
if (index >= 0 && index < vec.size()) {
vec[index] = value;
return true;
}
}
return false; // 边界检查失败
}
容器操作关键:
类型安全访问:通过模板确保类型正确性边界检查:防止越界访问零拷贝:直接操作容器内存,避免不必要的拷贝
🧲 智能指针支持
🔌 智能指针操作:
// 获取智能指针指向的对象
template
T* RTTI::Field::GetPointedObject(Object* obj) {
if (ReferenceType == ReferenceType_kSharedPointer) {
auto& ptr = GetValue
return ptr.get();
}
else if (ReferenceType == ReferenceType_kUniquePointer) {
auto& ptr = GetValue
return ptr.get();
}
return nullptr;
}
// 重置智能指针
template
void RTTI::Field::ResetPointer(Object* obj, T* newPtr) {
if (ReferenceType == ReferenceType_kSharedPointer) {
auto& ptr = GetValue
ptr.reset(newPtr);
}
else if (ReferenceType == ReferenceType_kUniquePointer) {
auto& ptr = GetValue
ptr.reset(newPtr);
}
}
智能指针支持特点:
安全访问:通过get()方法获取原始指针,避免直接暴露生命周期管理:支持reset等操作管理对象生命周期空指针检测:自动处理空指针情况
⚙️ 宏系统实现原理
🔬 宏展开示例:
// 原始代码
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
);
}
};
__RTTI__GameObject __RTTI__GameObject::r;
// 在GameObject类中添加
virtual RTTI* GetType() const override {
return &__RTTI__GameObject::r;
}
宏系统优势:
简化注册:用户只需简单宏调用即可完成复杂注册自动生成代码:在预处理阶段生成必要的RTTI代码隔离复杂性:用户无需了解底层实现细节
⚡ 性能优化设计
性能优化措施:
内存访问优化:
// 直接内存访问,无函数调用开销
#define DIRECT_ACCESS(ptr, offset) \
(*reinterpret_cast
reinterpret_cast
编译期类型解析:
template
constexpr FieldType DeduceFieldType() {
if constexpr (std::is_integral_v
else if constexpr (std::is_floating_point_v
// ... 其他类型
}
快速注册表查找:
class GlobalRegistry {
private:
static std::unordered_map
static std::unordered_map
public:
template
static void Register(const std::string& name) {
typeMap[name] = T::GetStaticType();
creatorMap[name] = []{ return new T(); };
}
};
🧪 完整操作示例
典型使用场景:
// 动态创建对象
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);
}
🔧 框架扩展机制
🧩 扩展示例:
// 添加自定义容器支持
template
struct is_custom_container : std::false_type {};
template
struct is_custom_container
// 在类型推导中添加处理分支
template
Field CreateField(const std::string& name, size_t offset) {
if constexpr (is_custom_container
Field field(name, offset, FieldType::CustomContainer);
// 实现自定义访问方法
field.GetElement = [](void* container, int index) {
return &static_cast
->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()) {
// 容器序列化
}
}
}
扩展能力:
新容器支持:通过模板特化添加新容器类型序列化:基于反射自动序列化/反序列化脚本绑定:自动生成脚本语言绑定代码编辑器集成:自动生成属性面板
📊 类型系统总览
详细类型支持矩阵
类型类别具体类型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
🏆 框架优势总结
高性能设计:
直接内存访问(零抽象开销)编译期类型解析(零运行时成本)哈希表快速查找(O(1)复杂度)
强大类型支持:
// 支持复杂嵌套类型
class Scene {
std::vector
std::map
RTTI_FIELD(objects);
RTTI_FIELD(colorPalette);
};
安全保证:
类型安全访问容器边界检查空指针检测
可扩展架构:
// 轻松添加新功能
RTTI_REGISTER_EXTENSION(Serialization, {
// 序列化实现
});
🧩 RTTI 轻量框架运行库实现
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
std::vector
std::queue
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* nameField = type->GetField("name");
std::string nameValue = nameField->GetValue
std::cout << "\nName: " << nameValue << "\n";
// 反射访问嵌套对象
RTTI::Field* posField = type->GetField("position");
Vector3& pos = posField->GetValue
std::cout << "Position: (" << pos.x << ", " << pos.y << ", " << pos.z << ")\n";
// 修改容器字段 - vector
RTTI::Field* scoresField = type->GetField("scores");
scoresField->SetValue(obj, 1, 100); // 修改第二个元素
// 访问容器字段 - queue
RTTI::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
// 获取智能指针字段
std::shared_ptr
childField->GetValue
std::cout << "Child name: " << childRef->name << "\n";
delete obj;
return 0;
}
Object.h:
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef offset_of
#define offset_of(type, member) ((size_t)&reinterpret_cast
#endif
#ifndef container_of
#define container_of(ptr, type, member) ((type*)((char*)static_cast
#endif
#ifndef type_of
#define type_of(type) (type::TypeOf())
#endif
class Object {
friend class RTTI;
public:
virtual RTTI* GetType() noexcept = 0;
virtual int GetHashCode() noexcept {
return (int)std::hash
}
};
template
constexpr T& constant_of(const T& v) noexcept {
return const_cast
}
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
#define RTTI_I(clazz) type_of(clazz);
class Object;
class RTTI {
protected:
typedef Object* (*NewObjectFx)();
static std::unordered_map
static std::unordered_map
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
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
TValue& GetValue(Object* obj) noexcept;
template
bool GetValue(Object* obj, int index, TValue& out) noexcept;
template
bool SetValue(Object* obj, int index, const TValue& value) noexcept;
template
bool GetValuePointer(Object* obj, int index, TValue** out) noexcept;
template
TValue& SetValue(Object* obj, const TValue& value) noexcept;
template
TValue& SetValue2(Object* obj, TValue&& value) noexcept;
template
bool GetFirstValuePointer(Object* obj, TValue** out) noexcept;
template
bool GetLastValuePointer(Object* obj, TValue** out) noexcept;
template
bool GetFirstValue(Object* obj, TValue& out) noexcept;
template
bool GetLastValue(Object* obj, TValue& out) noexcept;
private:
template
bool GetFirstValuePointer2(Object* obj, TValue** out) noexcept;
template
bool GetLastValuePointer2(Object* obj, TValue** out) noexcept;
};
Field* GetField(const std::string& method) noexcept;
const std::unordered_map
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
};
namespace __RTTI_IMPL__ {
class __RTTI_IMPL_FIELD_CLASS__{
template
struct HAS_MEMBER_TYPE_OF_FUNCTION final {
private:
template
static auto SFINAE_TEST(T*) noexcept -> decltype(std::declval().GetType(), std::true_type());
template
static std::false_type SFINAE_TEST(...) noexcept;
public:
static constexpr bool value = decltype(SFINAE_TEST
};
template
struct is_shared_ptr : std::false_type {};
template
struct is_shared_ptr
template
struct is_weak_ptr : std::false_type {};
template
struct is_weak_ptr
template
struct is_unique_ptr : std::false_type {};
template
struct is_unique_ptr
template
struct is_vector : std::false_type {};
template
struct is_vector
template
struct is_list : std::false_type {};
template
struct is_list
template
struct is_stack : std::false_type {};
template
struct is_stack
template
struct is_queue : std::false_type {};
template
struct is_queue
template
struct is_set : std::false_type {};
template
struct is_set
template
struct is_multiset : std::false_type {};
template
struct is_multiset
template
struct is_array : std::false_type {};
template
struct is_array
typedef T type;
static constexpr std::size_t length = N;
};
template
struct is_static_array : std::false_type {};
template
struct is_static_array
static constexpr std::size_t length = N;
};
public:
template
static RTTI* RTTI_GetType() noexcept {
if constexpr (std::is_base_of
RTTI* type = RTTI::GetType(_Ty::GetClassName());
if (NULL != type) {
return type;
}
return _Ty::TypeOf();
}
else {
return NULL;
}
}
template
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
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
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
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
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
return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kList);
}
else if constexpr (is_set<_Ty>::value) {
using _Ty2 = typename std::remove_reference
return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kSet);
}
else if constexpr (is_multiset<_Ty>::value) {
using _Ty2 = typename std::remove_reference
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
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
return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kQueue);
}
else {
return RTTI_GetField_2<_Ty>(name, offset, constant, RTTI::ListType_kNull);
}
}
template
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
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
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
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
TValue& RTTI::Field::GetValue(Object* obj) noexcept {
return *(TValue*)((char*)obj + Offset);
}
template
TValue& RTTI::Field::SetValue(Object* obj, const TValue& value) noexcept {
TValue& data = *(TValue*)((char*)obj + Offset);
data = value;
return data;
}
template
TValue& RTTI::Field::SetValue2(Object* obj, TValue&& value) noexcept {
TValue& data = *(TValue*)((char*)obj + Offset);
data = value;
return data;
}
template
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
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* data_ptr = std::addressof(data_ref);
*out = data_ptr + index;
return true;
}
else if (ListType == ListType_kVector) {
using _Ty2 = std::vector
_Ty2& vc = GetValue<_Ty2>(obj);
if (index >= (int)vc.size()) {
return false;
}
*out = vc.data() + index;
return true;
}
else {
return false;
}
}
template
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
bool RTTI::Field::GetFirstValuePointer2(Object* obj, TValue** out) noexcept {
TList& list = GetValue
auto tail = list.begin();
auto endl = list.end();
if (tail == endl) {
return false;
}
auto& ref = *tail;
*out = (TValue*)std::addressof(ref);
return true;
}
template
bool RTTI::Field::GetLastValuePointer2(Object* obj, TValue** out) noexcept {
TList& list = GetValue
auto tail = list.rbegin();
auto endl = list.rend();
if (tail == endl) {
return false;
}
auto& ref = *tail;
*out = (TValue*)std::addressof(ref);
return true;
}
template
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
*out = std::addressof(data_ref);
return true;
}
else if (ListType == ListType_kVector) {
using _Ty2 = std::vector
_Ty2& vc = GetValue<_Ty2>(obj);
if (vc.empty()) {
return false;
}
*out = vc.data();
return true;
}
else if (ListType == ListType_kList) {
using _Ty2 = std::list
return GetFirstValuePointer2<_Ty2>(obj, out);
}
else if (ListType == ListType_kSet) {
using _Ty2 = std::set
return GetFirstValuePointer2<_Ty2>(obj, out);
}
else if (ListType == ListType_kMultiSet) {
using _Ty2 = std::multiset
return GetFirstValuePointer2<_Ty2>(obj, out);
}
else if (ListType == ListType_kStack) {
using _Ty2 = std::stack
_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
_Ty2& queue = GetValue<_Ty2>(obj);
if (queue.empty()) {
return false;
}
*out = std::addressof(queue.front());
return true;
}
else {
return false;
}
}
template
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
*out = std::addressof(data_ref) + (ArraySize - 1);
return true;
}
else if (ListType == ListType_kVector) {
using _Ty2 = std::vector
_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
return GetLastValuePointer2<_Ty2>(obj, out);
}
else if (ListType == ListType_kSet) {
using _Ty2 = std::set
return GetLastValuePointer2<_Ty2>(obj, out);
}
else if (ListType == ListType_kMultiSet) {
using _Ty2 = std::multiset
return GetLastValuePointer2<_Ty2>(obj, out);
}
else if (ListType == ListType_kStack) {
using _Ty2 = std::stack
_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
_Ty2& queue = GetValue<_Ty2>(obj);
if (queue.empty()) {
return false;
}
*out = std::addressof(queue.back());
return true;
}
else {
return false;
}
}
template
bool RTTI::Field::GetFirstValue(Object* obj, TValue& out) noexcept {
TValue* ppv{ NULL };
if (!GetFirstValuePointer(obj, &ppv)) {
return false;
}
out = *ppv;
return true;
}
template
bool RTTI::Field::GetLastValue(Object* obj, TValue& out) noexcept {
TValue* ppv{ NULL };
if (!GetLastValuePointer(obj, &ppv)) {
return false;
}
out = *ppv;
return true;
}
RTTI.cpp:
#include "RTTI.h"
std::unordered_map
std::unordered_map
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++性能优势的同时提供了强大的运行时反射能力。