grk@sfsup.UUCP (G.R.Kuntz) (01/22/88)
I've recently been reading Brad Cox's book "Object Oriented Programming" and some of the examples that he gives are causing me a dilemma. Let's say we have a dynamically bound OO language and we want to write the following program (syntax is C++/SMALLTALK/kludge): class container { // ... public: message("add:"); message("weight"); }; class pen { // ... public: message("weight"); }; class pencil { // ... public: message("weight"); }; class eraser { // ... public: message("weight"); }; container pencilBox; pen pen1, pen2, pen3; pencil pencil1, pencil2; eraser eraser1, eraser2, eraser3; pencilBox.add(pen1); pencilBox.add(pen2); pencilBox.add(pen3); pencilBox.add(pencil1); pencilBox.add(pencil2); pencilBox.add(eraser1); pencilBox.add(eraser2); pencilBox.add(eraser3); cout << pencilBox.weight(); My question: is there any general way of writing the container class in a statically bound language without writing a ``container_thingie'' class and having all objects that may potentially be put in a container be derived from container_thingie? P.S. cat flames > /dev/null -- G. Ralph Kuntz N2HBN grk@attunix.att.com N2HBN @ KB1BD-4
jima@hplsla.HP.COM ( Jim Adcock) (01/26/88)
Hm, I'm not sure I can give a definitive answer to your question in general, but I may be able to clarify it in regards to the differences between Objective-C and C++. (I've been programming in Objective-C full time for a year or two now, and been programming in C++ during all my "free" time.) First, Objective-C is neither any more nor any less dynamically bound than C++. Objective-C semantics allows "any" message to be sent to any object (whether that object can handle that message or not, in general -- it can't) This in turn ties into Objective-C being an untyped language -- any object is represented by a pointer of type "id" to a chunk of memory in heap space. C++ semantics allows "messages" [virtual functions] to be applied only to objects for which that message is defined on the object's class, or its super classes. This in turn ties into the idea that C++ is a "typed" language, an object is represented by it's declared type and the values of the various bits in the chunk of memory that represents that object's values. [Where C++ allows that chunk of memory to be static, local, or in heap space.] In Objective-C you can imagine message name space as being a large sparse two-dimensional matrix, with the rows of the matrix corresponding to ALL the various classes, the columns of the matrix corresponding to ALL the various message names that are used anywhere in an Objective-C program, and the non-zero elements of the matrix being the addresses of the "C functions" that implement the Objective-C "message" for a particular DEFINED combination of classname/methodname. In general in Objective-C, most messages are NOT implemented for most classes, so this two-dimensional matrix would be EXTREMELY sparse (and extremely large) and most combinations of classname/messagename are undefined (IE zero addresses). Since this would not be storage-efficient, Objective-C uses a packed representation of this two dimensional matrix, with the result that to find the address of the "C function" code that implements a particular message a hash routine is required to turn the sparse representation of the matrix into the packed representation. The Objective-C routine that does this is typically called: "msg(objectpointer, functionamestrigpointer, parametersforthemessage ...)" This routine is called the Objective-C messenger. So, sending a message in Objective-C always requires executing this extra hash routine to find the address of the code to be executed. C++ requires that "messages" only be applied to objects for which that message is defined. This can be checked since C++ is a typed langauge. Thus in C++ there IS code that can be executed for every combination of classname/methodforthatclass. Thus, clearly, C++ doesn't need to use a sparse matrix representation to store the addresses of its "methods" and therefor doesn't need to call a hash routine every time C++ needs to find the address of a function. In particular, presently C++ has a separate one dimensional array of function addresses for each C++ class, where the elements of the array are all the "methods" [virtual functions] defined for that class. In Objective-C, if you want to "dynamically" edit which function-address is associated with a particular combination of classname/methodname, you write a link-editor that changes the address of the function found at the element of the packed representation of the sparse array corresponding to that classname/methodname. In C++, if you want to "dynamically" edit which function-address is associated with a particular combination of classname/methodname, you write a link-editor that changes the address of the function found at the element corresponding to that methodname of the array corresponding to that classname...... So again, the big differences between Objective-C and C++ is that basically Objective-C is an untyped language, C++ is a typed language. There are no great differences in "dynamic linking" capabilities. Back to your original question: Is there a general way of writing a container class in a "......" language? Answer: This is going to depend on what you want the container class to do. For example: If you want the container class to compute the sum of the weight of the objects in the container class, then all the various kinds of objects you put into container are going to have to know how to compute their own weight, and how to report that information in a uniform manner to the container class. This is true of both C++ and Objective-C. If all you want the container class to do is store the address of an object, and return that value at some point in time in the future .... then no problem. Objective-C has a problem in that it WILL allow you to compile, link and execute a program where some of the objects that are put in the container don't know how to compute their own weight. In which case you program will probably do something undesirable. C++ has the problem that it WON'T allow you to compile a program where some of the objects to be put into the container don't know how to compute their own weight -- unless you coerce some object types. Then C++ CAN have the same problem Objective-C has, namely then it WILL allow you to put objects in the container that don't know how to compute their own weight. I believe that when C++ has multiple inheritence, many of the problems associated with "container classes" will be greatly reduced. In C++ you will be able to create any "yourobject"-class that you want. If you want to be able to store "yourobject" in a "container" you can use multiple inheritence to glue "container" capabilities onto "yourobject", possibly overriding some of the "container" "messages" to give those "messages" capabilities particular to "yourobject". Then you are done. For example, one kind of "container" class might be a "memory-managed- ref-counted-garbage-collected-object-on-the-heap" class. Then IF your class needs these capabilities it would use multiple inheritance to glue them on. And IF your class DIDN'T need these capabilities, then it WOULDN'T have to "inherit" all this overhead !!!