C ++的属性和反射库?

时间:2020-03-05 19:00:09  来源:igfitidea点击:

大多数成熟的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)分发的。