这是个有点奇怪的问题。我的目标是理解语言设计决策,并确定在c++中反射的可能性。
为什么c++语言委员会没有在语言中实现反射?在不运行在虚拟机上的语言(如java)中反射是否太困难了? 如果要在c++中实现反射,会遇到什么挑战?
我想反射的用途是众所周知的:编辑器可以更容易地编写,程序代码将更小,可以为单元测试生成模拟等等。但是如果你能评论一下反射的用法就太好了。
这是个有点奇怪的问题。我的目标是理解语言设计决策,并确定在c++中反射的可能性。
为什么c++语言委员会没有在语言中实现反射?在不运行在虚拟机上的语言(如java)中反射是否太困难了? 如果要在c++中实现反射,会遇到什么挑战?
我想反射的用途是众所周知的:编辑器可以更容易地编写,程序代码将更小,可以为单元测试生成模拟等等。但是如果你能评论一下反射的用法就太好了。
当前回答
根据Alistair Cockburn的说法,在反射环境中不能保证子类型。
反射与潜在类型系统更相关。在c++中,你知道你得到了什么类型,你知道你可以用它做什么。
其他回答
我相信,如果c++要用作数据库访问、Web会话处理/http和GUI开发的语言,那么c++中的反射是至关重要的。缺乏反射阻碍了orm(如Hibernate或LINQ)、实例化类的XML和JSON解析器、数据序列化和许多其他东西(最初必须使用无类型数据来创建类的实例)。
可以使用软件开发人员在构建过程中可用的编译时开关 为了消除这种“一分钱一分货”的顾虑。
我是一个固件开发人员,不需要反射来从串口读取数据——那么很好,不使用交换机。但是作为一个想要继续使用c++的数据库开发人员,我经常要面对一个可怕的、难以维护的代码,这些代码在数据成员和数据库结构之间映射数据。
无论是Boost序列化还是其他机制都不能真正解决反射问题——它必须由编译器来完成——一旦完成,c++将再次在学校中教授,并用于处理数据处理的软件中
对我来说,这是问题#1(而原生线程原语是问题#2)。
Reflection requires some metadata about types to be stored somewhere that can be queried. Since C++ compiles to native machine code and undergoes heavy changes due to optimization, high level view of the application is pretty much lost in the process of compilation, consequently, it won't be possible to query them at run time. Java and .NET use a very high level representation in the binary code for virtual machines making this level of reflection possible. In some C++ implementations, however, there is something called Run Time Type Information (RTTI) which can be considered a stripped down version of reflection.
如果c++可以:
变量名、变量类型和const修饰符的类成员数据 函数参数迭代器(只有位置而不是名称) 函数名、返回类型和const修饰符的类成员数据 父类列表(与定义的顺序相同) 模板成员和父类的数据;扩展的模板(意味着实际的类型将可用于反射API,而不是“如何到达那里的模板信息”)
这足以在无类型数据处理的关键处创建非常容易使用的库,而无类型数据处理在当今的web和数据库应用程序中非常普遍 (所有的orm,消息传递机制,xml/json解析器,数据序列化等)。
例如,Q_PROPERTY宏(Qt框架的一部分)支持的基本信息 http://qt.nokia.com/doc/4.5/properties.html扩展到涵盖类方法和e) -将对c++和一般的软件社区非常有益。
当然,我所指的反射不会涵盖语义或更复杂的问题(如注释、源代码行号、数据流分析等)——但我也不认为这些是语言标准的一部分。
反射可以在c++中实现,并且已经在c++中实现过。
它不是原生的c++特性,因为它有一个沉重的成本(内存和速度),不应该由语言默认设置——语言是“默认最大性能”导向的。
因为你不应该为你不需要的东西付钱,而且正如你自己所说,编辑器比其他应用程序更需要它,那么它应该只在你需要的地方实现,而不是“强制”到所有的代码中(你不需要对你将在编辑器或其他类似应用程序中使用的所有数据进行反思)。
对于具有反射的语言来说,它是关于编译器愿意在目标代码中保留多少源代码来启用反射,以及有多少分析机制可用来解释反射的信息。除非编译器保留所有源代码,否则反射分析源代码可用事实的能力将受到限制。
c++编译器没有保留任何东西(好吧,忽略RTTI),所以在语言中没有反射。(Java和c#编译器只保留类、方法名和返回类型,所以你只能得到一点点反射数据,但你不能检查表达式或程序结构,这意味着即使在那些“启用反射”的语言中,你能得到的信息也非常少,因此你真的不能做很多分析)。
但是您可以跳出语言,获得完整的反射功能。C语言中关于反射的另一个堆栈溢出讨论的答案讨论了这个问题。