Paul said:
Presumably this is either a hope, a specification, or an assumption. It
is not, however, the actual result.
But the base class holding that reference doesn't exist either
since they're the same exact object. A derived instance has a
base instance inside it. Both their "this" pointers point to
the exact same memory location. If the derived object has been
freed, then (obviously) the base object (inside it) has also.
Java does not have pointers. It has references, which serve many of the
same roles, but no pointers. The difference is not academic, and may be
part of what is causing you such apparent frustration. For example,
there is no inherent logical inconsistency with any particular pointer
referring any particular place in memory, but there _is_ a logical
inconsistency with a reference whose referrent does not exist or has not
yet been fully constructed.
You are also missing Dale's point. He is describing a situation where
(a C++ implementation of) your design could potentially produce, hold,
and use rogue pointers. That would be a serious concern for program
stability and perhaps even system security. Perhaps it would never
happen in your particular app -- I don't know, as you have only provided
a schematic description. But even if not, who's to say that some future
modification by a developer not as familiar with your app's innards
(which could even be yourself, two years hence) would not introduce such
a problem?
The situation with Java is a bit different, I think. After analyzing my
example of the problem (one branch to your left in this thread) and
thinking about how the JVM works, my conclusion is that the worst that
can happen on the Java side is that you end up with a reference to an
object whose initialization was aborted midway. This is not equivalent
to a rogue pointer, because the object does exist, and will continue to
exist at least until it becomes unreachable from any running thread.
Its state may not be consistent, however, and use of the thing will not
be likely to reliably produce the expected results.
Once again you don't see that there's no paradox.
Whether or not it is a paradox, it _is_ a problem in your design, both
in Java and in C++. In the latter language the program evidently works,
but that does not validate the design quality. It is inherently unsafe
to pass around pointers / references to partially constructed objects,
and Java intentionally makes it difficult (albeit not impossible) to do so.
In your case, you have two classes of objects so tightly coupled
together that instances must come in pairs with each member of the pair
holding a final reference to the other. Good OOD principles call for
these things to be either combined into one or decoupled from each other.
One way of decoupling the objects would be to factor the links out into
a seperate object -- some kind of container that holds final references
to both of the others. Some of the code would need to go along to the
container too. Another, simpler way would be to do exactly as Dale
suggested, and assign one of the references after construction instead
of during. That doesn't achieve the same level of decoupling, but it's
better than what you have now. There are probably other, more
appropriate approaches as well, but they would depend on the nature and
roles of the classes involved.
John Bollinger
(e-mail address removed)