实现反射:如何查找类的父级

时间:2012-02-28 19:11:34

标签: c++ reflection generic-programming

我在这里遇到了一些挑战。我正在研究一个反射库,作为未来项目的练习和实用工具包。为了使它工作,我已经接受了不可避免的侵入性,我需要在课堂上添加至少一小部分代码。身体得到有价值的反思数据。

但是,我希望在这里尽可能地保持最小化。因此,在研究了一些现有的实现之后,我发现了一个适合我的概念。为简化起见,模式如下所示:

class Base
{
    int baseFoo;
    double baseBar[5];
    RTTINFO(baseFoo, baseBar);
};

(...)

Base sth;
std::cout << TypeInfo(sth).variables[0].name; << std::endl;
// I don't mind if the way of accessing the type info changes totally

使用一些通用编程,我可以实现隐藏这个RTTINFO宏和构建类型信息结构背后的任何东西。我可以检索类型,名称,数组大小等。但是当我想更进一步并引入继承时,像这样:

class Derived : public Base
{
    std::string foo;
    char* bar;
    /* RTTIPARENT(Base); <-- I want to avoid this */
    RTTINFO(foo, bar);
};

然后我想避免指定Base并且仍然能够进入其成员&#39; RTTI。我希望Base有一些方法可以在其RTTINFO(...)中为Derived走私某些提示以使其成为可能。那么..有吗?

主要要求是:

  1. 除了语言定义的地方之外,我不想在任何地方指定基类。而且我不想在任何宏中包装class Derived : public Base
  2. RTTIINFO可能会向受影响的班级添加任何必要的语言和记忆偏差。
  3. 我可以将任何我想要的内容放入RTTINFO宏,如果有必要,甚至可以放大量代码。
  4. Base和Derived都使用完全相同的RTTINFO宏,当然可以在进一步推断中重复使用。让我们省略多重继承问题,单继承似乎足够复杂。
  5. Derived无需访问Base的RTTI,它可能是处理RTTI数据的任何其他外部帮助程序类/函数。但是,需要支持私有成员变量。
  6. 我不介意编译和运行时成本 - 如果有任何计算,比如构建继承树,轮询所有现有类,无论如何,必须在运行时完成,总有一种方法可以移动它是程序的初始化阶段,对我来说没什么大不了的。
  7. 如果可能,请避免语言支持的RTTI,因为在某些项目中必须关闭它。无论如何,即使使用它,我也找不到解决方案。
  8. 不能添加额外的编译步骤。
  9. 一个注意事项:也许我可以使用type_info::before(),但即使它适用于常见的编译器,C ++标准也说我不能依赖继承关系。

    感谢您的任何建议!

    安德鲁

2 个答案:

答案 0 :(得分:3)

你不会完全反思当前的C ++ 03或C ++ 11编译器(因为即使是C ++ 11也没有真正的反射)。

您可以生成一些元类代码(以Qt MOC为例)

您可以扩展您的C ++编译器。如果是GCC,请考虑制作插件或MELT扩展程序。

答案 1 :(得分:2)

您可以考虑通过设置一种DSL(域特定语言)和一些代码生成框架来使用代码生成,该框架根据您在DSL中的类描述为您执行反射。这可能仅适用于数据容器和继承部分,而不适用于行为部分(即方法),但正如大多数Java倡导者无论如何都喜欢贫血对象模型,这完全符合这一趋势。

由于C ++具有真正的多重继承性,因此您有能力克服这种缺点并从生成的行为类中派生出行为类。

的Stefan