C++ 一个反射的例子

时间:2024-10-16 10:57:27

        在 C++ 中实现反射机制,虽然不像其他高级语言那样直接,但可以通过宏、模板和注册系统等技术来实现一个简易的反射系统。下面是一个完整的 C++ 反射机制示例,通过自定义类注册系统和宏定义,实现类的名称、属性、方法的反射 。

#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <functional>

// 存储类属性的元数据
struct Property {
    std::string name;
    std::function<void* (void*)> getter;
    std::function<void(void*, void*)> setter;
};

// 存储类方法的元数据
struct Method {
    std::string name;
    std::function<void(void*)> invoke;
};

// 存储反射类的信息
struct ClassInfo {
    std::string name;
    std::unordered_map<std::string, Property> properties;
    std::unordered_map<std::string, Method> methods;
};

// 全局类注册表
std::unordered_map<std::string, ClassInfo> classRegistry;

// 注册类信息
void RegisterClass(const std::string& className, const ClassInfo& info) {
    classRegistry[className] = info;
}

// 通过类名获取类信息
ClassInfo* GetClassInfo(const std::string& className) {
    auto it = classRegistry.find(className);
    if (it != classRegistry.end()) {
        return &it->second;
    }
    return nullptr;
}

// 定义类的宏,自动注册类名
#define REFLECT_CLASS(className) \
    static ClassInfo _classInfo; \
    static void Register() { \
        _classInfo.name = #className; \
        RegisterClass(#className, _classInfo); \
    } \
    static ClassInfo& GetClassInfo() { return _classInfo; } \
    virtual const char* GetClassName() const { return #className; }

// 定义属性的宏,自动注册属性
#define REFLECT_PROPERTY(className, propertyName) \
    className::_classInfo.properties[#propertyName] = {#propertyName, \
        [](void* obj) -> void* { return &static_cast<className*>(obj)->propertyName; }, \
        [](void* obj, void* value) { \
            using PropertyType = decltype(static_cast<className*>(obj)->propertyName); \
            static_cast<className*>(obj)->propertyName = *static_cast<PropertyType*>(value); \
        }};

// 定义方法的宏,自动注册方法
#define REFLECT_METHOD(className, methodName) \
    className::_classInfo.methods[#methodName] = {#methodName, [](void* obj) { static_cast<className*>(obj)->methodName(); }};

// 定义 Person 类
class Person {
public:
    REFLECT_CLASS(Person)

        // 属性
        std::string name;
    int age;

    Person(const std::string& n, int a) : name(n), age(a) {}

    // 方法
    void PrintInfo() {
        std::cout << "Name: " << name << ", Age: " << age << std::endl;
    }
};

// 注册属性和方法
ClassInfo Person::_classInfo;
void RegisterPerson() {
    REFLECT_PROPERTY(Person, name)
        REFLECT_PROPERTY(Person, age)
        REFLECT_METHOD(Person, PrintInfo)
}

int main() {
    // 注册类
    RegisterPerson();

    // 创建对象
    Person person("Alice", 30);

    // 获取类信息
    ClassInfo* info = GetClassInfo("Person");

    if (info) {
        // 获取并修改属性
        Property* nameProp = &info->properties["name"];
        std::string* namePtr = static_cast<std::string*>(nameProp->getter(&person));
        std::cout << "Original Name: " << *namePtr << std::endl;

        // 修改名字
        std::string newName = "Bob";
        nameProp->setter(&person, &newName);
        std::cout << "New Name: " << person.name << std::endl;

        // 调用方法
        Method* printMethod = &info->methods["PrintInfo"];
        printMethod->invoke(&person);
    }

    return 0;
}