据我所知,如果我有一个类如下:
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())。
能够循环遍历它们将是生成班级规模报告等的有用且简单的方法。这是不可能做到的,还是有办法(甚至使用外部工具)?
答案 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根据您在任意符号表中找到的内容转换代码(或生成派生代码)方式。