English 中文(简体)
将类视为一等对象
原标题:
  • 时间:2009-03-03 04:06:09
  •  标签:

我正在阅读《哈利波特与火焰杯》,在原型部分的开头,我读到了这句话:

This benefit applies primarily to languages like C++ that don t treat classes as first class objects.

我从未使用过C++,但我对面向对象编程有很好的理解,然而,这对我来说并没有什么意义。有人能解释一下吗?(我使用过C、Python、Java、SQL,如果有帮助的话。)

最佳回答

为了使一个类成为一种一等对象,编程语言需要支持诸如允许函数接受类(而非实例)作为参数、能够在容器中保存类,以及能够从函数中返回类等操作。

以一个包含一流类的语言Java为例。任何对象都是其类的实例。这个类本身是java.lang.Class的一个实例。

问题回答

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

"Reduced subclassing. Factory Method (107) often produces a hierarchy of Creator classes that parallels the product class hierarchy. The Prototype pattern lets you clone a prototype instead of asking a factory method to make a new object. Hence you don t need a Creator class hierarchy at all. This benefit applies primarily to languages like C++ that don t treat classes as first-class objects. Languages that do, like Smalltalk and Objective C, derive less benefit, since you can always use a class object as a creator. Class objects already act like prototypes in these languages." - GoF, page 120.

正如史蒂夫所说的

I found it subtle in so much as one might have understood it as implying that /instances/ of classes are not treated a first class objects in C++. If the same words used by GoF appeared in a less formal setting, they may well have intended /instances/ rather than classes. The distinction may not seem subtle to /you/. /I/, however, did have to give it some thought.

I do believe the distinction is important. If I m not mistaken, there is no requirement than a compiled C++ program preserve any artifact by which the class from which an object is created could be reconstructed. IOW, to use Java terminology, there is no /Class/ object.

在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# and Java programs can be aware of their own classes because both .NET and Java runtimes provide reflection, which, in general, lets a program have information about its own structure (in both .NET and Java, this structure happens to be in terms of classes).

There s no way you can afford reflection without relying upon a runtime environment, because a program cannot be self-aware by itself*. But if the execution of your program is managed by a runtime, then the program can have information about itself from the runtime. Since C++ is compiled to native, unmanaged code, there s no way you can afford reflection in C++**.

...

* Well, there s no reason why a program couldn t read its own machine code and "try to make conclusions" about itself. But I think that s something nobody would like to do.

** Not strictly accurate. Using horrible macro-based hacks, you can achieve something similar to reflection as long as your class hierarchy has a single root. MFC is an example of this.

Template metaprogramming has offered C++ more ways to play with classes, but to be honest I don t think the current system allows the full range of operations people may want to do (mainly, there is no standard way to discover all the methods available to a class or object). That s not an oversight, it is by design.





相关问题
热门标签