由于课程项目要求,要能够在程序运行时获取场景中对象的属性与方法,在网上了解到了反射机制,但C++都未能支持反射机制,在C++中要实现类似Java等语言的反射机制需要另外写代码保存类型相关信息,然后在运行时使用。所以了解到了RTTR, rttr提供对象的成员数据类型,通过rttr获取每一个对象的的属性,读取起数据类型和值,然后利用这些信息自动保存数据,也能利用这些信息自动解析数据。
在官网下载完成后,cmake即可。
rttr的使用
1、首先写一些类或结构体
-
// 颜色类
-
enum class
color
-
{
-
red,
-
green,
-
blue
-
};
-
-
// (x,y)点
-
struct
point2d
-
{
-
point2d() {}
-
point2d(
int x_,
int y_) :
x(x_),
y(y_) {}
-
int x =
0;
-
int y =
0;
-
};
-
-
// 形状类
-
struct
shape
-
{
-
shape(std::string n) :
name(n) {}
-
-
void set_visible(bool v) { visible = v; }
-
bool get_visible() const {
return visible; }
-
-
color color_ = color::blue;
-
std::string name =
"";
-
point2d position;
-
std::map<color, point2d> dictionary;
-
-
RTTR_ENABLE()
-
private:
-
bool visible =
false;
-
};
-
-
// 圆
-
struct
circle : shape
-
{
-
circle(std::string n) :
shape(n) {}
-
-
double radius =
5.2;
-
std::vector<point2d> points;
-
-
int no_serialize =
100;
-
-
RTTR_ENABLE(shape)
-
};
2、手动注册属性方法和构造函数
-
RTTR_REGISTRATION
-
{
-
rttr::registration::
class_<shape>(
"shape")
-
.
property(
"visible", &shape::get_visible, &shape::set_visible)
-
.
property(
"color", &shape::color_)
-
.
property(
"name", &shape::name)
-
.
property(
"position", &shape::position)
-
.
property(
"dictionary", &shape::dictionary)
-
;
-
-
rttr::registration::
class_<circle>(
"circle")
-
.
property(
"radius", &circle::radius)
-
.
property(
"points", &circle::points)
-
.
property(
"no_serialize", &circle::no_serialize)
-
(
-
metadata(
"NO_SERIALIZE",
true)
-
)
-
;
-
-
rttr::registration::
class_<point2d>(
"point2d")
-
.
constructor()(rttr::policy::ctor::as_object)
-
.
property(
"x", &point2d::x)
-
.
property(
"y", &point2d::y)
-
;
-
-
-
rttr::registration::
enumeration<color>(
"color")
-
(
-
value(
"red", color::red),
-
value(
"blue", color::blue),
-
value(
"green", color::green)
-
);
-
}
3、使用1——将对象转为json数据
①先创建一个circle的对象
-
circle c_1("Circle #1");
-
shape& my_shape = c_1;
-
-
c_1.
set_visible(
true);
-
c_1.points = std::
vector<point2d>(
2,
point2d(
1,
1));
-
c_1.points[
1].x =
23;
-
c_1.points[
1].y =
42;
-
-
c_1.position.x =
12;
-
c_1.position.y =
66;
-
-
c_1.radius =
5.123;
-
c_1.color_ = color::red;
-
-
-
c_1.dictionary = { { {color::green, {
1,
2} }, {color::blue, {
3,
4} }, {color::red, {
5,
6} } } };
-
-
c_1.no_serialize =
12345;
②转为json数据,只需要一句话
json_string = io::to_json(my_shape);
结果:
4、使用2——利用已有的json数据,新生成一个对象
接下来创建一个新的圆circle2,name="Circle #2"
circle c_2("Circle #2");
将circle1的json数据,反序列化后的内容用于给circle2的属性赋值
io::from_json(json_string, c_2);
输出circle2的json数据后,也能验证和circle的数据内容是一致的。