C ++的属性和反射库?
大多数成熟的C ++项目似乎都有自己的反射和属性系统,即用于定义可以通过字符串访问并可以自动序列化的属性。至少我参与的许多C ++项目似乎都在重新发明轮子。
我们是否知道C ++的任何优秀开源库都支持反射和属性容器,特别是:
- 通过宏定义RTTI和属性
- 通过代码访问RTTI和属性
- 自动序列化属性
- 监听属性修改(例如OnValueChanged)
解决方案
回答
QT不是通用的,而是QT通过元编译器支持的,它是GPL。
通过与QT人员交谈,我的理解是,使用纯C ++无法做到这一点,因此需要moc。
回答
通常,这是C ++语言的一个臭名昭著的弱点,因为需要标准化以使反射实现可移植且值得使用的东西不是标准的。我想到了调用约定,对象布局和符号修饰,但是还有其他一些。
标准缺乏方向性,意味着编译器实现者将做一些不同的事情,这意味着很少有人有动力编写可移植的反射库,这意味着需要反射的人会重新发明轮子,但仅够满足他们的需求。这是无限的,现在就到了。
回答
这是当C ++遇到反射时得到的:
无论我们选择什么,它都可能具有可怕的宏,难以调试的代码或者怪异的构建步骤。我已经看到一种系统会从DevStudio的PDB文件自动生成序列化代码。
严重的是,对于小型项目,编写保存/加载函数(或者使用流运算符)会更容易。实际上,这可能也适用于大型项目,这很明显正在发生,并且如果结构发生更改,我们通常通常仍然需要更改代码。
回答
我们可以看看下面的两个工具。我从未使用过它们中的任何一个,所以我无法告诉我们它们的实用性。
XRTTI:
Xrtti is a tool and accompanying C++ library which extends the standard runtime type system of C++ to provide a much richer set of reflection information about classes and methods to manipulate these classes and their members.
OpenC ++:
OpenC++ is C++ frontend library (lexer+parser+DOM/MOP) and source-to-source translator. OpenC++ enables development of C++ language tools, extensions, domain specific compiler optimizations and runtime metaobject protocols.
回答
我看了好一阵子这些东西,但它们往往很笨拙。它们可能会阻止我们使用继承,或者使用奇怪的构造函数等。最后,它们最终负担太多,而不是方便。
这种公开我现在使用的成员的方法非常轻巧,例如,我们可以浏览一个类进行序列化或者将所有名为" x"的字段设置为0。它也是静态确定的,因此非常快。无需担心库代码或者代码源的任何层会干扰构建过程。它概括为嵌套类型的层次结构。
使用一些宏来设置编辑器,以自动编写其中的一些内容。
struct point { int x; int y; // add this to your classes template <typename Visitor> void visit(Visitor v) { v->visit(x, "x"); v->visit(y, "y"); } }; /** Outputs any type to standard output in key=value format */ struct stdout_visitor { template <typename T> void visit(const T& rhs) { rhs.visit(this); } template <typename Scalar> void visit (const Scalar& s, const char* name) { std::cout << name << " = " << s << " "; } }
回答
有一个新项目使用完全不同的方法在C ++中提供了反射:CAMP。
https://github.com/tegesoft/camp
CAMP不使用预编译器,使用类似于boost.python或者luabind的语法手动声明类/属性/函数/...。当然,如果愿意,人们可以使用gccxml或者open-c ++之类的预编译器来生成此声明。
它仅基于纯C ++和boost标头,并且由于模板元编程的强大功能,它支持任何类型的可绑定实体(例如,继承和奇怪的构造函数都不是问题)。
它是根据MIT许可(以前是LGPL)分发的。