From: Martin Krischik on
Am 06.06.2010, 12:13 Uhr, schrieb Simon Wright <simon(a)pushface.org>:

> "Martin Krischik" <krischik(a)users.sourceforge.net> writes:
>
>> One should just
>> make a habit of defining classes like this:
>>
>> virtual Base
>> {
>> public:
>> virtual ~Base ()
>> {
>> …
>> }
>> }
>>
>> And suddenly all your virtual inheritance needs work flawlessly.
>
> I suppose there must be some cost to doing this? or the language
> definition would require it to be always so.

Yes indeed, you have virtual dispatch not only on the methods but on the
instance variables as well. Sounds worth then it is. It means the internal
structure of a child type changes from (Ada pseudo code):

record Child_Type is
Parent_Data : Parent_Type;
end record

to

record Child_Type is
Hidden_Parent_Data : Parent_Type;
Parent_Data : constant access Parent_Type := Hidden_Parent_Data'Access;
end record

The compiler will ensure that Hidden_Parent_Data exist only once - but
there may be any amount of Parent_Data which all point to the same
Hidden_Parent_Data. And the funny part: The technology used to archive
this is the very same you use to implement interfaces. Once you have the
scaffolding for Interfaces in place you can have virtual base classes as
well.

Main problem with multiple inheritance was in C++ itself where default is
“fast” not ”save”. For the Eiffel users it was never a problem because
there virtual base classes are default. And I just see I made a mistake in
my original post. It should have been:


class Parent
{
public:
virtual ~Parent ()
{

}
}

class Child
virtual public Parent
{

}

but main problem stay: not enough C++ programmer have known about virtual
inheritance and the diamond problem only pops up at Grand_Child level and
lower (that means one has to plan ahead to avoid it). This in turn given
multiple inheritance a bad name. But if you do it right it works just
beautifully.

The real lesson learned: “doing it right” must be default and “make it
fast” must be an optional extra to be taught in very advanced level
courses only.

Martin
--
Martin Krischik
mailto://krischik(a)users.sourceforge.net
https://sourceforge.net/users/krischik
From: Maciej Sobczak on
On 6 Cze, 10:55, "Martin Krischik" <krisc...(a)users.sourceforge.net>
wrote:

> > Some people still think this is still a better trade-off over C++ styled
> > multiple inheritance because of the dreaded "diamond" problem.
>
> which is easily solved by marking classes virtual. One should just make a  
> habit of defining classes like this:
>
> virtual Base
>    {
>    public:
>      virtual ~Base ()
>        {
>        …
>        }
>    }

That will not work. Not just because it is invalid syntax, but because
"virtualness" is a property of the relation between classes, not the
property of any particular class.

> And suddenly all your virtual inheritance needs work flawlessly. There are  
> just too many C++ programmers out there who do not know that.

Not really, see my answer to your other post.

--
Maciej Sobczak * http://www.inspirel.com

YAMI4 - Messaging Solution for Distributed Systems
http://www.inspirel.com/yami4
From: Maciej Sobczak on
On 6 Cze, 14:04, "Martin Krischik" <krisc...(a)users.sourceforge.net>
wrote:

> > I suppose there must be some cost to doing this? or the language
> > definition would require it to be always so.
>
> Yes indeed, you have virtual dispatch not only on the methods but on the  
> instance variables as well.

No, such concept does not even make sense - instance variables
themselves have no behavior and therefore cannot be "overriden". With
virtual inheritance there is only one copy of the given instance
variable within the whole object, so even the word "dispatch" cannot
be applied there, as "dispatch" relates to "choice" and there is no
choice.

> Main problem with multiple inheritance was in  C++ itself where default is  
> “fast” not ”save”.

No. Neither of these (non-virtual vs. virtual) is "fast" or "safe" in
itself.

Considering the performance aspect, the layout of variables within the
object is determined *statically* (I have already explained that there
is no "dispatch" involved), which means that there is no run-time cost
in finding the given data item. All instance variables have some
offset from the "beginning" of the object and that offset is computed
statically, whether inheritance is virtual or not. There is no
particular reason for any performance difference in data access, so it
does not make any sense to say than one mode is "fast", while the
other is not. Both are "fast" (it's C++, remember? ;-) ).

Considering the safety aspect, the choice between non-virtual and
virtual is design-dependent. Both make sense in some domain.
For example, my mobile phone is able to send both text and multimedia
messages. In both cases I might want to see the count of messages that
were already sent and I want these counters to be *distinct*, not
shared.
This is a perfectly valid design (pseudo-code):

class Countable;
class TextMessager : public Countable;
class MultimediaMessager : public Countable;
class Phone : public TextMessager, public MultimediaMessager, ...;

Now I have *separate* counters, both accessible with appropriate name
paths (which makes perfect sense).

Why is this a default? I don't know, but it's consistent with the fact
that the whole object model is value-oriented, not interface-oriented.
It's neither right nor wrong.

(note: you might argue that the counter should be held by composition,
not by extension - this is orthogonal to this discussion)

> but main problem stay: not enough C++ programmer have known about virtual  
> inheritance

Again, that knowledge would not necessarily help them, as the use of
virtual inheritance is not automatically justified.

> The real lesson learned: “doing it right” must be default

Both ways are right. The default one is consistent with the overall
object model.

> and “make it  
> fast” must be an optional extra

Both are fast.

--
Maciej Sobczak * http://www.inspirel.com

YAMI4 - Messaging Solution for Distributed Systems
http://www.inspirel.com/yami4
From: Martin Krischik on
Am 07.06.2010, 10:13 Uhr, schrieb Maciej Sobczak
<see.my.homepage(a)gmail.com>:

> That will not work. Not just because it is invalid syntax, but because
> "virtualness" is a property of the relation between classes, not the
> property of any particular class.

Read my post below.

Martin

--
Martin Krischik
mailto://krischik(a)users.sourceforge.net
https://sourceforge.net/users/krischik
From: Martin Krischik on
Am 07.06.2010, 10:13 Uhr, schrieb Maciej Sobczak
<see.my.homepage(a)gmail.com>:

>> And suddenly all your virtual inheritance needs work flawlessly. There
>> are
>> just too many C++ programmers out there who do not know that.

> Not really, see my answer to your other post.

So you think that all C++ programmers are perfect and know the ISO/IEC
14882:2003 from memory? Well the amount of C++ programming has reduced in
recent years - maybe those who work in the business these days are of a
better quality then those I knew. who knows.

Martin
--
Martin Krischik
mailto://krischik(a)users.sourceforge.net
https://sourceforge.net/users/krischik