[Uml-devel] ambiguity

P. Fleury fleury at users.sourceforge.net
Wed Jan 15 17:52:04 UTC 2003


Andrew Sutton wrote:

>this is supposed to ensure that duplicate instances of the RefObject class do 
>not exist in instances of derived types. so, in theory, returning a reference 
>to a RefObject for an instance of AliasType will not result in an ambiguous 
>base class error.
>  
>
Yes, this is exactly the meaning of virtual inheritance. This is a 
programming language specific issue, though, and it goes hand in hand 
with the problem of the calling of constructors and destructors (and 
their calling order). It is up to the compiler to guarantee that the 
constructor is called once only, at least once, and in the order 
specified by the language (in C++, after all the base classes have been 
initialized).

>so far so good, right? maybe. all the classes with the exception of AliasType 
>are abstract and *might* appear in other circular inheritance hierarchies. 
>
Note that an inheritance graph is always directed, and having a directed 
graph like the one you describe (or like the ones you can build with 
inheritance), you never get a cycle in the graph-theory sense. If you 
write code which has a cycle, the compiler will kindly let you know :-), 
as in

class D2; // needing forward declaration of rinheritance is sort of 
suspect in the first place
class Base : public D2 {};
class D1 : public Base {};
class D2 : public D1 {};

>the problem is easy to understand in small doses, but what about generalized 
>references "mid-hierarchy". in the example given above, there are multiple 
>instances of ModelElement in the AliasType class. if we wanted to return a 
>reference to ModelElement for an AliasType, we'd probably get an ambiguous 
>base class error. one solution might be to always virtually derive abstract 
>base classes, but i don't know if that would work. i haven't seen any 
>examples where the most derived class virtually derives its multiple bases.
>  
>
Multiple inheritance is a tricky field, Stroustrup said it himself. It 
should be used in small doses anyway, or not visible at a certain point 
in the hierarchy tree (inheritance encapsulation if you will).
Because of this complexity, some languages have decided to not allow it 
in the first place (like Java). Note that the concept of Java interfaces 
(corresponding to pure virtual base class) does not lead to any 
ambiguity, because there are no data members and you cannot make an 
inheritance graph which has different implementations of a method in the 
paths along the inheritance graph.

>furthermore, there seems to be some caveat the the most derived class must 
>call the constructors for virtually derived classes. if the entire 
>inheritance hierarchy (excepting non-abstract classes) is virtually derived, 
>then the non-abstract classes would have to construct ever single class in 
>the inheritance hierarchy.
>  
>
The call to constructors is solved globally for a given class, and it 
entirely a compiler issue (and guarantee). The compiler computes the 
inheritance tree, then computes the constructor ordering, then calls 
them in that order. The order of calls of constructor is not clearly 
specified in the C++ book, but it is advised to not rely on the call 
order of the different constructors.

>another good question is whether or not we find multiple instances of 
>non-virtually derived Ref classes in instantiated objects. all the 
>documentation that i've found indicates that the multiple instances of the 
>virtual base class are "unified" (as opposed to distinct). if that's the 
>case, are the base classes of the VBC also unified?
>  
>
Sometimes you want them be unified, sometimes you want them to be 
distinct. Therefore C++ gives you the virtual modified for inheritance.
But I think that the cases where multiple inheritance of public 
non-pure-virtual classes is really needed can be easily counted. Using 
pure-virtual base classes solves the problem (the Java interfaces), 
using private inheritance mostly solves the problem too (inheritance of 
the implementation only), and otherwise most problems turn out to be 
solvable by aggregation and delegation, which do not have as many 
pitfalls as multiple inheritance. A weak argument for avoiding the 
problem, I know, but nonetheless a realistic one...

In my experience, I have used it only a single time, over the roughly 
100'000 lines of C++ code I have written so far. And I did not miss it 
in Java at all.

But does UML specify a way to indicate if the multiply inherited base 
class is unified or not ? Will it in future ?

--Pascal





More information about the umbrello-devel mailing list