From: Dirk van Deun on
Martin Vuille (jpmv27(a)yahoo.com) wrote:

: In your example, let's say that Node has some data members. Then
: Root contains a Node with those data members and so does MyNode.
: Unless you do what is required by the language (e.g., use virtual
: inheritance in C++), MyRoot will contain two Nodes, one by virtue
: of containing a Root, and one by virtue of containing a MyNode.

It seems to me that a lot of problems of multiple inheritance are caused
by its interpretation as a union instead of as an intersection, and of
the subclass containing, not being-a-kind-of, its superclasses. In the
intersection model, Root is a kind of Node, and so is MyNode. So
something that is both Root and MyNode, will also be a kind of Node. It
will not be a kind of Node twice, that is nonsense. So I would say
that virtual inheritance should be the default, and non-virtual
inheritance considered a very dirty hack. If you want something to be a
kind of something else, inherit. If you want something to contain
something else, use an instance variable.

Dirk van Deun
--
Ceterum censeo Redmond delendum
From: Martin Vuille on
dvandeun(a)vub.spam-me-not.ac.be (Dirk van Deun) wrote in
news:flu7tt$gnn$1(a)snic.vub.ac.be:

> Martin Vuille (jpmv27(a)yahoo.com) wrote:
>
>: In your example, let's say that Node has some data members.
>: Then Root contains a Node with those data members and so
>: does MyNode. Unless you do what is required by the language
>: (e.g., use virtual inheritance in C++), MyRoot will contain
>: two Nodes, one by virtue of containing a Root, and one by
>: virtue of containing a MyNode.
>
> It seems to me that a lot of problems of multiple inheritance
> are caused by its interpretation as a union instead of as an
> intersection, and of the subclass containing, not

That doesn't make any sense to me. If A multiply derives from B
and C, that says to me "A 'is a' B _and_ A 'is a' C". That
sounds like a union to me.

I'm not sure what you mean by "intersection", but I can't see
how you would mean that literally since the intersection of Root
and MyNode would be Node. Surely MyRoot is more than just a
Node.

> being-a-kind-of, its superclasses. In the intersection
> model, Root is a kind of Node, and so is MyNode. So
> something that is both Root and MyNode, will also be a kind
> of Node. It will not be a kind of Node twice, that is

Well, it might be, depending on the context.

In D&E, Stroustrup gives an example of MI where the "link" base
class allows objects derived from it to be placed in a linked
list. In the example, the most derived class inherits twice from
"link" and, in fact, 'is a' "link" twice, as it is expected to
be part of two distinct linked lists, so there must be two
instances of "link" state.

He gives another example where "window" is the repeated base
class and, in that example, only one instance is desired since
there is only one physical window.

He goes on to say "I saw no reason for virtual base classes
being more useful or fundamental than ordinary base classes or
vice versa [...]."

> nonsense. So I would say that virtual inheritance should be
> the default, and non-virtual inheritance considered a very
> dirty hack. If you want something to be a kind of something
> else, inherit. If you want something to contain something
> else, use an instance variable.

I'm not convinced that virtual inheritance should be the
default. From the point of view of reuse it seems to me that
this would be very dangerous. I think that explicit action
(i.e., making the inheritance relationship virtual) should be
required before overlaying two sets of state.

In D&E, Stroustrup says that he made non-virtual inheritance the
default because "the implementation is cheaper in time and space
and because 'programming using virtual bases is a bit trickier
than programming using non-virtual bases. [...]'"

All that having beem said, I have to agree that many examples of
MI (even Stroutrup's) are less than compelling and do seem be
crying out for composition rather than inheritance.

MV

--
I do not want replies; please follow-up to the group.
From: Dirk van Deun on
: > It seems to me that a lot of problems of multiple inheritance
: > are caused by its interpretation as a union instead of as an
: > intersection, and of the subclass containing, not

: That doesn't make any sense to me. If A multiply derives from B
: and C, that says to me "A 'is a' B _and_ A 'is a' C". That
: sounds like a union to me.

: I'm not sure what you mean by "intersection", but I can't see
: how you would mean that literally since the intersection of Root
: and MyNode would be Node. Surely MyRoot is more than just a
: Node.

Yeah, I should have thought a bit longer about my terminology. I
meant to say that classes with equal parts should be interpreted as sets
of properties, so that they can have intersections. And as in set
theory, the properties in the intersections would "be there" only once.

: > being-a-kind-of, its superclasses. In the intersection
: > model, Root is a kind of Node, and so is MyNode. So
: > something that is both Root and MyNode, will also be a kind
: > of Node. It will not be a kind of Node twice, that is

: Well, it might be, depending on the context.

That it cannot be, was not a conclusion, but a starting point. It
would be interesting to take this as a given and see what
happens. I think that it would "tame" multiple inheritance, by forcing
the programmer to use alternatives whenever he wants to use M.I.
for "has a" relationships.

: In D&E, Stroustrup gives an example of MI where the "link" base
: class allows objects derived from it to be placed in a linked
: list. In the example, the most derived class inherits twice from
: "link" and, in fact, 'is a' "link" twice, as it is expected to
: be part of two distinct linked lists, so there must be two
: instances of "link" state.

I would say that being a link twice is nonsense. Something can serve
as a link in two different ways, but it will not *be* two links.
It might however *have* two "linkings".

Again, this is a proposed starting point for thinking about M.I., not
a conclusion based on current M.I. languages. It is only based
on the natural language semantics of "to be".

: I'm not convinced that virtual inheritance should be the
: default. From the point of view of reuse it seems to me that
: this would be very dangerous. I think that explicit action
: (i.e., making the inheritance relationship virtual) should be
: required before overlaying two sets of state.

It would indeed be dangerous if you expressed "has a" relationships
using M.I. But after having neutralised the danger by using M.I. only
for "is a" relationships (strictly using the natural language meaning
of "to be"), reuse will, I believe, become much harder to do wrong.

I think there is a nice trade-off to be found there.

Dirk van Deun
--
Ceterum censeo Redmond delendum