From: cflatter@nrao.edu (Chris Flatters)
Subject: Flattening (Was: Complexity in the eyes...V2.0)
Reply-To: cflatter@nrao.edu
Organization: NRAO
Date: Thu, 17 Dec 1992 18:51:51 GMT


In article 8150@tagsys.com, andrew@tagsys.com (Andrew Gideon) writes:
>1.	karl@BofA.com (Karl Nicholas) asks why a consumer of classes
>	would be peeking around the internals of those classes, 
>	and any possible superclasses.
>
>	A lot of people (well...a few) provided answers.  I provided
>	a couple of simplisitic ones (I was rushed!): debugging and
>	understanding.
>
>	maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) agreed with the
>	"understanding" issue.
>
>	I still think, however, that good documentation would solve
>	that problem.  The fact that I've never seen documentation
>	of sufficient quality may be significant, however.  Perhaps
>	some nifty tool which reads class definitions provides a
>	"flattened" interface?

[A quick aside for people who may not be familiar with the concept:
A flattened class interface combines the interface of a class with
its ancestors in such a way as to produce a new class, without
inheritance, that behaves in the same way as the original class
(apart from type compatibility, of course).]

Experience with Eiffel shows that such a tool is useful but is not, in
itself, sufficient for class documentation.  I once heard Eiffel class
documentation (which is usually obtained obtained by flattening a class
and extracting information from it) described as being somewhere
between not enough and barely adequate: this seems to be a fairly
accurate description.

Unfortunately there are at least two problems in flattening C++ classes
(this has really been done to death before on the net).

1) A flattened C++ class would contain only syntactic information and
would not provide any semantic information (ie. it wouldn't say
what it actually does).  This information must be provided in comments
which must be preserved by the flattening process.  This throws the
burden of providing adequate class documentation back onto the programmer
who writes the interface.  This is also true for Eiffel, although the
fact that Eiffel definitions may contain semantic information (class
invariants, preconditions and postconditions) make life a little easier.

2) A C++ class behaves differently when it is called directly than
when it is called through a pointer or a reference.  For example

	class A
            {
            ....
            virtual void foo();
            ....
            }

	class B: public A
            {
            ...
            virtual void foo();
            }

        main()
            {
            B b;
            A& a_ref = b;
            A a = b;

            a.foo()	// calls A::foo()
	    a_ref.foo() // calls B::foo()
            }

And there are also difficulties involving non-virtual functions: a class 
access by a reference or pointer to one of its ancestors may behave like
its ancestor for some member function calls and itself for others.  In
general the behaviour of a C++ class will depend on the type of pointer
or reference it is accessed through.  This makes a flattening a concept
of dubious value for C++.

	Chris Flatters
	cflatter@nrao.edu