通过C ++类的成员

时间:2010-12-30 05:32:15

标签: c++ static-analysis

据我所知,如果我有一个类如下:

class TileSurface{
   public:
      Tile * tile;
      enum Type{
         Top,
         Left,
         Right
      };
      Type type;
      Point2D screenverts[4]; // it's a rectangle.. so..
      TileSurface(Tile * thetile, Type thetype);
};

没有简单的方法以编程方式(使用模板或其他)遍历每个成员并执行打印类型的操作(例如,typeinfo的typeid(Tile).name())。

能够循环遍历它们将是生成班级规模报告等的有用且简单的方法。这是不可能做到的,还是有办法(甚至使用外部工具)?

6 个答案:

答案 0 :(得分:2)

在C ++中根本不可能。你需要像Reflection这样的东西来实现它,这是C ++没有的。

就编译后的代码而言,“类”不存在 - 变量的名称及其类型在汇编中没有意义,因此它们不会被编码到二进制的。

(注意:当我说“在C ++中不可能”时,我的意思是“不可能在语言中内置” - 你当然可以在C ++中编写一个可以实现这种东西的C ++解析器......)

答案 1 :(得分:1)

我不同于传统的智慧。 C ++确实拥有它;它不是C ++标准的一部分,但我见过的每一个C ++编译器都会发出这种类型的元数据供调试器使用。

此外,调试数据库的两种格式几乎涵盖了所有现代编译器:pdb(Microsoft格式)和dwarf2(几乎所有其他)。

答案 2 :(得分:1)

没有。没有简单的方法。如果把“简单的方法”放在一边,那么用C ++就可以做任何可以想象的事情。

如果您只想转储数据内容的运行时间,那么最简单的方法是为您感兴趣的每个YourClass实现运算符<<(ostream&,YourClass const&)。更复杂的是实现访问者模式,但是使用访问者模式,您可能会有不同的访问者完成不同的报告,访问者也可能会做其他事情,而不仅仅是生成报告。

如果您希望将其作为静态分析(程序未运行,您希望生成报告),则可以使用调试器数据库。或者,你可以分析一些编译器生成的AST(g ++和CLang有生成它的选项)并从中生成报告。

如果你真的需要运行时反射,那么你必须将它构建到你的类中。这涉及开销。例如,您可以使用公共基类,并将类的所有数据成员也放入数组中。通常用与以更平等的理由反映的语言编写的应用程序进行通信(最老的例子是Lisp)。

答案 3 :(得分:0)

如果从公共typeinfo-provider-baseclass派生所有类型的成员变量,那么你可以得到它。它比Java更有用,但可能。

答案 4 :(得分:0)

外部工具:您提到需要类别大小等报告.--

Doxygen可以帮助http://www.doxygen.nl/manual/features.html生成类成员列表(包括继承的成员)。

答案 5 :(得分:0)

我们的DMS Software Reengineering Toolkit就是你所谓的“外部工具”,用于提取/转换任意代码。 DMS是通过显式语言定义参数化的通用编译器技术。它具有C,C ++,Java,COBOL,PHP等语言定义。

对于C,C ++,Java和COBOL版本,它提供对解析树和符号表信息的完全访问。该符号表信息包括您可能想要从“反射”获得的数据类型。如果您的目标是枚举一些字段或方法,并使用它们某些东西,可以使用DMS根据您在任意符号表中找到的内容转换代码(或生成派生代码)方式。