[comp.lang.c++] dynamic vs. static binding

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 !!!