[comp.lang.c++] VERY LONG

dcw@doc.ic.ac.uk (Duncan C White) (06/05/87)

A friend and I are trying to assess the suitability of C++ as a replacement
for SIMULA, in the context of teaching a 2nd year UG Computer Science course
about Simulation.

We have found one basic difference between the two, and various sub-problems,
which we would like to ask more experienced C++ programmers about.

If any of the questions are stupid, or ignorant, please be kind and gently
correct us...

*** WARNING: THIS ARTICLE IS APPROX 300 LINES LONG... HIT 'j' NOW IF YOU'RE
*** NOT INTERESTED..


Terminology/Abbreviations:
-------------------------

We are using more general object-orientated terms in place of C++'s ones.
Specifically:

o	a method	a procedure in a class
o	a subclass	a descendant class
o	a superclass	an ancestor class

"The Book" is the 'C++ Programming Language' [ Bjarne Stroustrup, AT&T ]

A reference such as "S:7.5.2" means "Section 7.5.2 of the Book"

Also, we will use a sort of "pseudo-C++/SIMULA" for all the examples,
irrespective of minor details like syntax... :-)


Question 1:	There seems to be an ambiguity in the Book which could cause
----------	a lot of confusion if not cleared up:

For example, given the following [an extract from 'class hierarchies' S:7.5.2]

	class employee
	class manager        : employee
	class director       : manager
	class vice_president : manager
	class president      : vice_president

there are several SUBCLASSES of employee:

	manager, director, vice_president and president

whereas manager is the ONLY IMMEDIATE SUBCLASS of employee.
[In general, however, there may be several IMMEDIATE SUBCLASSES:
director AND vice_president are BOTH immediate subclasses of manager]

Which of these terms corresponds to 'derived class' ?


Similarly, there is ONLY one IMMEDIATE SUPERCLASS of director [manager] :
does this correspond to the base class definition ?  Or is employee a base
class of director, as well ?


A Basic Difference :	After some initial experimenting [ which took us 3
------------------	days, and involved fairly heavy rewriting of this
			article !! ], we became aware of a very basic
			difference between SIMULA and C++ :

We had assumed that the basic facilities SIMULA and C++ provide would be the
same : after all, the Introduction says that C++ was designed [ via C with
classes ] as an alternative to SIMULA, but less expensive at run-time.

However, SIMULA allows the following:

>	class vehicle ...		// class defns
>	class car : vehicle ...
>	class fourwheeler : car ...
>
>	ref( vehicle ) v;

NOTE : in SIMULA, all class variables are declared and initialised separately
so in this example, 'v' is declared as a reference to a vehicle, [reference
appears to be the same term as in C++].  v has not been initialised yet.
The C++ style declaration 'vehicle v' is meaningless in SIMULA.

Clearly, then, v could be initialised [ SIMULA actually uses ':-' as a special
assignment operator for refs ] by the following:

>	v = new vehicle;

However, SIMULA allows an important 'other' style of initialization :

>	v = new car;

which initialises v, but not to a vehicle-instance: to a car-instance [ car
must be a subclass of vehicle ]

C++ objects [vehemently] to this kind of use : probably because it has many
implications for run-time behaviour.

This basic problem comes to light again and again :

o	You can't declare a function which takes a parameter of type vehicle,
	and then call it with an expression which is a car-instance.

o	You can't define a 'list of vehicles' into which you can put any
	subclass-instances [ cars, planes, boats, pogo-sticks, minis, fords,
	aston martins etc.. ]

o	Associated operators like 'in' and 'qua' [ see below ] aren't available

It seems to us, that the omission of such facilities in C++ is a major
obstacle to 'object-orientated' programming : the usual SIMULA approach no
longer works.  Why the hell can't a list of vehicles contain some cars, some
planes, some horse-drawn carriages, and some pogo-sticks ??


Question 2:	Is this omission as serious as it appears ?  Can the same
----------	facilities be provided another way, or is there a separate
		"C++ programming metaphor" which entails a different way
		of analysing problems so that the missing features are never
		needed ??

NOTE: The Book seems to suggest two related techniques :

	generic vectors [ S:1.16 ]

which suggests writing macros to 'build' class definitions for specific
subclass lists [ eg, declare( vector, int ) ]
However, this builds an 'integer-vector' class definition, rather than a
'vector of things which are any subclasses of integer'

AND:

	polymorphic vectors [ S:17 ]

However, this technique seems to rely on 'void *' to contain a pointer to
the elements: surely this completely defeats the type-checking scheme ?


Explanation of 'in' and 'qua' :
-----------------------------

1). The boolean SIMULA function :

	i in c

returns true if the instance, i, is an instance of the given class, c,
or if i is an instance of any subclass of c [ false otherwise ]

For example:

	a 'car' instance is in 'car'
	a 'car' instance is ALSO in 'vehicle'
	a 'fourwheeler' instance is in 'fourwheeler', 'car' and 'vehicle'

2). The polymorphic SIMULA function :

	i qua c

"qualifies" the instance, i, as a class, c. [ more explanation below example ]

For example: given the following:

>	ref( vehicle ) v;
>	v = new car;		// vehicle v is a car: C++ would already object

The following use, despite actually being logically correct, fails to compile :

>	print v.wheels;		// attempt to print the number of wheels
>				// that the car-instance v has.

whereas this is ok:

>	print (v qua car).wheels;

Note: the semantics of qua are a strange mixture of compile-time and run-time 
events.  At compile-time, v must be an instance of a car, or an instance of a
superclass of car, otherwise a compile time error is generated.
However, at run-time, v is checked to see that it actually is 'in' car, and
a fatal run-time error is generated if not.


Finding the Immediate Superclass:	We realized that 'in' was not defined
--------------------------------	some time before we understood the
					Basic Problem, and we tried to define
					'in' ourselves :

It seemed quite simple, we thought, just have a static name for each class
and then search upwards through the class hierarchy.

This would mean declaring one universal superclass, which would contain the
function 'in'.  All other classes would be subclasses of this, inheriting 'in'
from the universal class [ therefore, the code would only need to be defined
once ! ]

Question 3 :	Can anyone think of a nicer way to implement in ?
----------	We tried :

>typedef int boolean ;
>
>class universal_class {
>	static char *name = "universal_class";

This, of course, caused us to run straight into the

	'initialization of static class members'

problem discussed a few articles ago..  ( of course, we didn't read that
article until we had wasted several hours trying various increasingly
desperate and mucky methods ... :-)

Anyway, after we had seen the solution to this problem, we continued:

>	boolean in( char *str )
>	{
>		return strcmp( this.name, str ) == 0
>		|| (
>			strcmp( this.name, "universal_class" )
>			&& super::in( str )
>		);
>	}
>}; // end class universal_class

We had naively assumed that super, or something very like it, would exist,
and would allow you to use a method of the GENERAL immediate superclass of
an instance, rather than the method of the instance itself.

We knew that, if you know the name of the immediate superclass, you can use:

	superclass_name::method

but this would require a version of 'in' for every subclass.


Question 4 : Does C++ have an equivalent of super ?  Can it be defined ?
----------

As soon as we started thinking about it, we realised that SIMULA does not have
'super' either.   We couldn't understand why this function was not available
in SIMULA, since SIMULA undoubtedly maintains enough run-time information to
implement it.  However, the only concrete use we have thought of [so far] for
'super' is when defining 'in'....

So, we supppose, because SIMULA has 'in' already defined, it doesn't need
to have 'super', whereas C++ has neither 'in' nor 'super'..


Conclusion:
----------

There are many aspects in C++ which we like [ operator overloading and true
reference variables especially ] but it does seem to be, in some sense, a
"weaker kind" of class-based language than SIMULA.  Please respond to this
message by e-mail, and I will summarise to the net if there is much interest..

Apologies for the length of this article...

Finally,

	nacnuD, emit ruoy rof sknahT

	(well, everyone says I'm backward :-)

-----------------------------------------------------------------------------
JANET address : dcw@uk.ac.ic.doc| Snail Mail :  Duncan White,
--------------------------------|               Dept of Computing,
  This space intentionally      |               Imperial College,
  left blank......              |               180 Queen's Gate,
  (paradoxical excerpt from     |               South Kensington,
  IBM manuals)                  |               London SW7
----------------------------------------------------------------------------
Tel: UK 01-589-5111 x 4982/4991
----------------------------------------------------------------------------