The Distributed Reference Graph
shapj@us.ibm.com
shapj@us.ibm.com
Mon, 14 Dec 1998 09:49:28 -0500
Initialization code is indeed a special case. Until the object is in an
internally consistent state, no external invocations of the object can
safely be permitted. Note that the semantics of initialization is beastly
hard. Stroustrup has commented on this somewhat in his "Design and
Evolution of C++"
The specific problem that MarcS identifies, however, seems simple to
mitigate (in E, but not in Java). If each object carries an "I have been
initialized" bit, the second and subsequent calls to the initializer can be
flagged as errors.
In C++, I have often found that it reduces code replication to have all
constructors invoke a common initialization routine. Strictly speaking,
this violates the language spec, but it works in all real implementations.
My tentative belief, therefore, is that the "has been initialized" bit
should be set on exit from the constructor. This actually eliminates the
need for an extra bit, as the type field of the object cannot be updated
until the constructor has run to completion.
Hmm. This raises an ugly Java question. Let class B be derived from class
A. We now create a new instance of B. A's constructor must run first, at
the completion of which the type of the object is legitemately A. B's
constructor is then run. During the execution of B's constructor, the
object is no longer quite an A but not yet quite a B. Does the language
permit a helper method (e.g. an init routine) defined by B to be called
from within B's constructor? If so, and if this method ask's the object to
report it's current "class", what does the object answer? Is there, in
principle, a correct answer?
Sorry about the digression, but MarcS has raised a point that's going to
bite me in the butt elsewhere, so I'ld like to understand what is
semantically well-formulated in addition to understanding what actually
happens.
shap