refl_s 是一个轻量级的 C++ 头文件库,旨在为 C++ 结构体和类提供非侵入式的静态反射能力。它通过使用宏和编译期计算在编译时获取类型信息,避免了对现有代码的侵入性修改。
refl_s 库提供了一系列强大的功能,允许您在编译时对 C++ 类和结构体进行静态反射。以下示例将展示其主要用法。
在使用 refl_s 之前,您需要使用 REFL 宏为您的类或结构体注册需要反射的成员。
#include "refl_s.h"
#include <string>
struct MyStruct {
int id;
std::string name;
double value;
};
// 注册 MyStruct 的成员
REFL(MyStruct, id, name, value)
// 包含静态成员和不同访问修饰符的示例
class MyClass {
public:
int public_member;
static int public_static_member;
protected:
double protected_member;
static double protected_static_member;
private:
char private_member;
static char private_static_member;
};
// 注册 MyClass 的成员
REFL(MyClass, public_member, public_static_member, protected_member,
protected_static_member, private_member, private_static_member)您可以通过成员的字符串名称来获取其引用,这对于运行时动态访问成员非常有用。
#include "refl_s.h"
#include <iostream>
struct Config {
int timeout;
std::string host;
};
REFL(Config, timeout, host)
void example_get_member() {
Config cfg = {1000, "localhost"};
// 获取并修改 'timeout' 成员
int& timeout_ref = GetMember<int>(cfg, "timeout");
std::cout << "Original timeout: " << timeout_ref << std::endl;
timeout_ref = 2000;
std::cout << "New timeout: " << GetMember<int>(cfg, "timeout") << std::endl;
// 获取 'host' 成员
std::string& host_ref = GetMember<std::string>(cfg, "host");
std::cout << "Host: " << host_ref << std::endl;
}您可以获取指定成员的访问修饰符(public, protected, private)的字符串表示。
#include "refl_s.h"
#include <iostream>
class Settings {
public:
int public_setting;
protected:
bool protected_setting;
private:
double private_setting;
};
REFL(Settings, public_setting, protected_setting, private_setting)
void example_access_specifier() {
std::cout << "public_setting: " << GetMemberAccessSpecifierInString<Settings>("public_setting") << std::endl;
std::cout << "protected_setting: " << GetMemberAccessSpecifierInString<Settings>("protected_setting") << std::endl;
std::cout << "private_setting: " << GetMemberAccessSpecifierInString<Settings>("private_setting") << std::endl;
}refl_s 支持对静态成员的反射和访问。
#include "refl_s.h"
#include <iostream>
class Counter {
public:
static int count;
};
// 注册静态成员
REFL(Counter, count)
int Counter::count = 0; // 初始化静态成员
void example_static_members() {
// 直接通过类名获取静态成员引用
int& count_ref_class = GetStaticMember<int, Counter>("count");
count_ref_class = 20;
std::cout << "Count via class: " << Counter::count << std::endl;
}refl_s 可以与自定义的序列化/反序列化函数配合使用,实现结构体或类的自动转换。
#include "refl_s.h"
// 示例结构体
struct User {
int id;
std::string name;
double score;
};
REFL(User, id, name, score)
void example_serialization() {
User user1 = {1, "Bob", 99.5};
std::string serialized_data = serialize(user1);
std::cout << "Serialized: " << serialized_data << std::endl;
User user2;
deserialize(user2, serialized_data);
std::cout << "Deserialized User ID: " << user2.id
<< ", Name: " << user2.name
<< ", Score: " << user2.score << std::endl;
}refl_s 是一个头文件库。您只需将 refl_s.h 文件包含到您的项目中即可。
本项目目前仅在以下编译器上进行了测试:
g++llvm-clang++
需要注意的是,在继承场景下,对反射的支持情况目前不是很良好。