我正在阅读GoF书籍,在原型部分的开头,我读到了这个:
此福利主要适用于 像C ++这样不需要处理的语言 类作为第一类对象。
我从未使用过C ++,但我对OO编程有很好的理解,但这对我来说并没有任何意义。任何人都可以详细说明这一点(我使用过\ use:C,Python,Java,SQL,如果有帮助的话。)
答案 0 :(得分:8)
对于要成为第一类对象的类,语言需要支持诸如允许函数将类(非实例)作为参数,能够在容器中保存类以及能够从函数返回类的操作。
有关具有第一类类的语言的示例,请考虑使用Java。任何对象都是其类的实例。该类本身就是java.lang.Class的一个实例。
答案 1 :(得分:7)
对于其他人来说,这是完整的引用:
“减少子类化。工厂方法 (107)经常产生一个层次结构 与之平行的创作者类 产品类层次结构。原型 pattern允许您克隆原型 而不是要求工厂方法 制作一个新对象。因此,你没有 需要一个Creator类层次结构。 此优惠主要适用于 像C ++这样不需要处理的语言 类作为第一类对象。 像Smalltalk和。这样的语言 目标C,得益少, 因为你总是可以使用一个类 作为创造者的对象。类对象 已经像这些中的原型一样 语言。“ - GoF,第120页。
我发现它非常微妙 可能已经理解为暗示 / classes / of classes不是 用C ++处理了第一类对象。 如果GoF使用相同的单词出现 在不太正式的环境中,他们可能会 很有意图/实例/而非 比上课。区别可能不是 对你来说似乎很微妙。 / I /,但是, 我不得不考虑一下。
我确实相信这一区别 重要。如果我没有弄错的话 没有要求比编译的C ++ 程序保留任何工件 对象所在的类 创建可以重建。 IOW, 使用Java术语,没有 / Class / object。
答案 2 :(得分:4)
在Java中,每个类本身都是一个从java.lang.Class派生的对象,它允许您从程序中访问有关该类,其方法等的信息。 C ++不是那样的;类(与其对象相对)在运行时无法真正访问。有一个名为RTTI(运行时类型信息)的工具,可以让你按照这些方式做一些事情,但它非常有限,我相信有性能成本。
答案 3 :(得分:2)
你使用过python,它是一种具有一流类的语言。您可以将类传递给函数,将其存储在列表中等。在下面的示例中,函数new_instance()返回它传递的类的新实例。
class Klass1:
pass
class Klass2:
pass
def new_instance(k):
return k()
instance_k1 = new_instance(Klass1)
instance_k2 = new_instance(Klass2)
print type(instance_k1), instance_k1.__class__
print type(instance_k2), instance_k2.__class__
答案 4 :(得分:2)
C#和Java程序可以知道自己的类,因为.NET和Java运行时都提供reflection,这通常会让程序获得有关其自身结构的信息(在.NET和Java中,这个结构碰巧是在类中。)
如果不依赖于运行时环境,就无法承受反射,因为程序本身不能自我识别*。但是如果程序的执行由运行时管理,那么程序可以从运行时获得有关自身的信息。由于C ++被编译为本机非托管代码,因此无法用C ++ **进行反射。
...
*嗯,没有理由为什么一个程序无法读取自己的机器代码并“试图对自己做出结论”。但我认为这是没有人愿意做的事情。
**不严格准确。使用可怕的基于宏的黑客攻击,只要您的类层次结构具有单个根,就可以实现类似于反射的操作。 MFC就是一个例子。
答案 5 :(得分:2)
模板元编程为C ++提供了更多的方法来玩类,但说实话我不认为当前的系统允许人们可能想做的全部操作(主要是,没有标准的方法来发现所有的类或对象可用的方法)。这不是疏忽,而是设计。