Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将类视为第一类对象_C++_Oop_Prototype_Design Patterns - Fatal编程技术网

C++ 将类视为第一类对象

C++ 将类视为第一类对象,c++,oop,prototype,design-patterns,C++,Oop,Prototype,Design Patterns,我在读GoF的书,在原型部分的开头我读到: 这一好处主要适用于 像C++这样的不被对待的语言 类作为第一类对象 我从来没有使用过C++,但是我对OO编程有很好的理解,但是,这对我来说并没有任何意义。有人能详细说明一下吗(如果有帮助的话,我用过\使用:C、Python、Java、SQL)。对于其他人,这里是完整的引用: “简化的子类化工厂方法” (107)通常产生一个层次结构 与 产品类层次结构。原型 模式允许您克隆原型 而不是要求工厂方法 创建一个新对象。因此您不需要 根本不需要创建者类层次结构

我在读GoF的书,在原型部分的开头我读到:

这一好处主要适用于 像C++这样的不被对待的语言 类作为第一类对象


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

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

“简化的子类化工厂方法” (107)通常产生一个层次结构 与 产品类层次结构。原型 模式允许您克隆原型 而不是要求工厂方法 创建一个新对象。因此您不需要 根本不需要创建者类层次结构。 这一好处主要适用于 像C++这样的不被对待的语言 类作为第一类对象。 像Smalltalk和 目标C,获得较少的收益, 因为你总是可以使用一个类 对象作为创建者。类对象 在这些系统中已经像原型一样工作了 语言。”-戈夫,第120页

作为

我发现它在一件事上是微妙的 可能会理解为暗示 类的/实例/不是 在C++中处理了第一类对象。 如果出现了GoF使用的相同词语 在不太正式的场合,他们可能会 我们有意向/实例/相反 而不是上课。这种区别可能不存在 对你来说似乎很微妙/然而,我, 我确实需要考虑一下

我确实认为区别在于 重要的。如果我没弄错的话,还有 不需要编译的C++ 程序保留任何通过 从中创建对象的类 创建的对象可以重建。换句话说 要使用Java术语,没有 /类/对象


对于要成为第一类对象的类,该语言需要支持这样的操作:允许函数将类(而不是实例)作为参数,能够在容器中保存类,以及能够从函数返回类


对于一个具有第一类的语言的例子,考虑java。任何对象都是其类的实例。该类本身就是的一个实例。

在Java中,每个类本身都是一个对象,从Java.lang.class派生而来,它允许您从程序中访问有关该类及其方法等的信息。C++不是这样的;类(与其对象相反)在运行时不是真正可访问的。有一个叫做RTTI(运行时类型信息)的工具,可以让您按照这些思路做一些事情,但它非常有限,而且我相信它会带来性能成本

您已经使用了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__
C#和Java程序可以知道自己的类,因为.NET和Java运行时都提供了这些类,一般来说,它们让程序拥有关于自己结构的信息(在.NET和Java中,这种结构恰好是以类为单位的)

如果不依赖运行时环境,您就无法承受反射,因为程序本身无法自我感知*。但是,如果程序的执行是由运行时管理的,那么程序可以从运行时获得有关自身的信息。因为C++被编译成本地的非托管代码,所以在C++中不可能有反射能力。

*嗯,程序没有理由不能读取自己的机器代码并“尝试得出结论”。但我认为这是没人愿意做的事


**不完全准确。使用可怕的基于宏的攻击,只要类层次结构只有一个根,就可以实现类似于反射的功能。MFC就是这样的一个例子。

模板元编程为C++提供了更多的方法来处理类,但老实说,我认为当前的系统不允许人们可能要做的所有操作(主要是没有一种标准的方法来发现一个类或对象可用的所有方法)。这不是疏忽,这是出于设计。

你在混淆概念。没有运行时这一事实并不意味着类可能是第一类公民和/或反射。反射可以用元编程手动实现,没有真正的技术障碍。只有在像C++这样的静态语言中看到的反射是MFC的DeCalayOrthor。RTTI的主要问题是它的表示是非标准的(编译器定义的),并且它只存在于至少有一个虚拟方法的对象中,因此它的范围有限。除此之外,它只包含类型信息,与反射无关。我也看到了这个链接(但并没有真正回答我所问的问题),我在提问之前尝试查找答案:)。不过,感谢您详细阐述完整的引文。我认为关键是最后一行:“哦,用Java术语来说,没有/Class/object。”这对我来说很有意义。谢谢