views:

328

answers:

6

I was reading the GoF book and in the beginning of the prototype section I ready this:

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

I've never used C++ but I do have a pretty good understanding of OO programming, yet, this doesn't really make any sense to me. Can anyone out there elaborate on this (I have used\use: C, Python, Java, SQL if that helps.)

+4  A: 

For everybody else, heres the full quote:

"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.

As Steve puts it,

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.

John Ellinwood
I saw this link too (but doesn't really answer what I am asking IMO), I did try to look the answer up before asking :). Thanks for elaborating on the full quote though.
javamonkey79
I think the key is that very last line: "IOW, to use Java terminology, there is no /Class/ object." This makes sense to me. Thanks.
javamonkey79
+4  A: 

For a class to be a first class object, the language needs to support doing things like allowing functions to take classes (not instances) as parameters, be able to hold classes in containers, and be able to return classes from functions.

For an example of a language with first class classes, consider Java. Any object is an instance of its class. That class is itself an instance of java.lang.Class.

Mr Fooz
+3  A: 

In Java, every class is an object in and of itself, derived from java.lang.Class, that lets you access information about that class, its methods etc. from within the program. C++ isn't like that; classes (as opposed to objects thereof) aren't really accessible at runtime. There's a facility called RTTI (Run-time Type Information) that lets you do some things along those lines, but it's pretty limited and I believe has performance costs.

ceo
The main problem with RTTI is that its representation is non-standard (compiler defined) and that it only exists for objects that have at least one virtual method, so it has limited scope. Besides the fact that it only contains type info, and nothing close to reflection.
David Rodríguez - dribeas
+1  A: 

You've used python, which is a language with first-class classes. You can pass a class to a function, store it in a list, etc. In the example below, the function new_instance() returns a new instance of the class it is passed.

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__
bstpierre
+1  A: 

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.

Eduardo León
You are mixing concepts. The fact that there is no runtime does not have any implication on the possibility of classes being first class citizens and/or reflection. Reflection can be achieved manually with metaprogramming, there is no real technical impediment.
David Rodríguez - dribeas
The only thing similar to reflection I have seen in a static language like C++ is MFC's DECLARE_DYNAMIC. And the implementation, IMHO, sucks.
Eduardo León
+1  A: 

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.

Max Lybbert