将类视为第一类对象

时间:2009-03-03 04:06:09

标签: c++ oop prototype design-patterns

我正在阅读GoF书籍,在原型部分的开头,我读到了这个:

  

此福利主要适用于   像C ++这样不需要处理的语言   类作为第一类对象。

我从未使用过C ++,但我对OO编程有很好的理解,但这对我来说并没有任何意义。任何人都可以详细说明这一点(我使用过\ use:C,Python,Java,SQL,如果有帮助的话。)

6 个答案:

答案 0 :(得分:8)

对于要成为第一类对象的类,语言需要支持诸如允许函数将类(非实例)作为参数,能够在容器中保存类以及能够从函数返回类的操作。

有关具有第一类类的语言的示例,请考虑使用Java。任何对象都是其类的实例。该类本身就是java.lang.Class的一个实例。

答案 1 :(得分:7)

对于其他人来说,这是完整的引用:

  

“减少子类化。工厂方法   (107)经常产生一个层次结构   与之平行的创作者类   产品类层次结构。原型   pattern允许您克隆原型   而不是要求工厂方法   制作一个新对象。因此,你没有   需要一个Creator类层次结构。   此优惠主要适用于   像C ++这样不需要处理的语言   类作为第一类对象。   像Smalltalk和。这样的语言   目标C,得益少,   因为你总是可以使用一个类   作为创造者的对象。类对象   已经像这些中的原型一样   语言。“ - GoF,第120页。

作为Steve puts it

  

我发现它非常微妙   可能已经理解为暗示   / 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 ++提供了更多的方法来玩类,但说实话我不认为当前的系统允许人们可能想做的全部操作(主要是,没有标准的方法来发现所有的类或对象可用的方法)。这不是疏忽,而是设计。