[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Dealing with a Diamond of Death

Rocketmagnet

10/27/2008 10:09:00 PM

Hi all,

I have been kind of forced (honestly) into writing a class structure
which contains a Diamond of Death, and I'm not entirely sure what to
do about it. This is a simplified version of my class structure:


class entity
{
public:
entity() {}

int a;
};


class item : public entity
{
public:
item() {}

int b;
};


class loop : public virtual item
{
public:
loop() {}

int c;
};


class path : public virtual item
{
public:
path() {}

int d;
};

class test : public path, public loop
{
public:
test() {}

int e;
};



int _tmain(int argc, _TCHAR* argv[])
{
ENTITY *entity_test = new test();
ENTITY *entity_loop = new loop();

loop* l = (loop*)entity_loop; // cannot convert a 'ENTITY*' to a
'loop*'
// conversion from a virtual base
class is implied

test* t = (test*)entity_test; // cannot convert a 'ENTITY*' to a
'test*'
// conversion from a virtual base
class is implied

return 0;
}


Can anyone tell me what I'm doing wrong?

Many thanks in advance for any help or advice.

Hugo Elias
20 Answers

Pete Becker

10/27/2008 10:17:00 PM

0

On 2008-10-27 18:08:43 -0400, Rocketmagnet <hugo.elias@virgin.net> said:

> Hi all,
>
> I have been kind of forced (honestly) into writing a class structure
> which contains a Diamond of Death, and I'm not entirely sure what to
> do about it.

I don't understand. Having a common virtual base class is sometimes an
appropriate design. Why do you call it a "Diamond of Death"?

> This is a simplified version of my class structure:

Simplified to the point of incorrectness, since the code in main
(that's what _tmain means, right?) refers to ENTITY but the nearest
thing here is entity.

>
>
> class entity
> {
> public:
> entity() {}
>
> int a;
> };
>
>
> class item : public entity
> {
> public:
> item() {}
>
> int b;
> };
>
>
> class loop : public virtual item
> {
> public:
> loop() {}
>
> int c;
> };
>
>
> class path : public virtual item
> {
> public:
> path() {}
>
> int d;
> };
>
> class test : public path, public loop
> {
> public:
> test() {}
>
> int e;
> };
>
>
>
> int _tmain(int argc, _TCHAR* argv[])
> {
> ENTITY *entity_test = new test();
> ENTITY *entity_loop = new loop();
>
> loop* l = (loop*)entity_loop; // cannot convert a 'ENTITY*' to a
> 'loop*'
> // conversion from a virtual base
> class is implied

You need to use dynamic_cast here, and in order to do that, ENTITY or
entity, whichever is the real class, needs to have at least one virtual
function.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jeff Schwab

10/27/2008 10:53:00 PM

0

Pete Becker wrote:
> On 2008-10-27 18:08:43 -0400, Rocketmagnet <hugo.elias@virgin.net> said:

>> I have been kind of forced (honestly) into writing a class structure
>> which contains a Diamond of Death, and I'm not entirely sure what to
>> do about it.
>
> I don't understand. Having a common virtual base class is sometimes an
> appropriate design. Why do you call it a "Diamond of Death"?

Because proponents of languages that don't support multiple inheritance
properly have gone out of their way to convince everyone how terrible it
is. This is always a frustrating discussion; nobody can tell you *why*
it's bad, but they're sure it's a bomb waiting to go off. No exceptions.

In fairness, it is kind of nasty in some other languages. Python comes
to mind, because Python automatically breaks the diamond at run-time in
an unpleasant way.

Ross A. Finlayson

10/28/2008 2:08:00 AM

0

Pete Becker wrote:
> On 2008-10-27 18:08:43 -0400, Rocketmagnet <hugo.elias@virgin.net> said:
>
>> Hi all,
>>
>> I have been kind of forced (honestly) into writing a class structure
>> which contains a Diamond of Death, and I'm not entirely sure what to
>> do about it.
>
> I don't understand. Having a common virtual base class is sometimes an
> appropriate design. Why do you call it a "Diamond of Death"?
>
>> This is a simplified version of my class structure:
>
> Simplified to the point of incorrectness, since the code in main (that's
> what _tmain means, right?) refers to ENTITY but the nearest thing here
> is entity.
>
>>
>>
>> class entity
>> {
>> public:
>> entity() {}
>>
>> int a;
>> };
>>
>>
>> class item : public entity
>> {
>> public:
>> item() {}
>>
>> int b;
>> };
>>
>>
>> class loop : public virtual item
>> {
>> public:
>> loop() {}
>>
>> int c;
>> };
>>
>>
>> class path : public virtual item
>> {
>> public:
>> path() {}
>>
>> int d;
>> };
>>
>> class test : public path, public loop
>> {
>> public:
>> test() {}
>>
>> int e;
>> };
>>
>>
>>
>> int _tmain(int argc, _TCHAR* argv[])
>> {
>> ENTITY *entity_test = new test();
>> ENTITY *entity_loop = new loop();
>>
>> loop* l = (loop*)entity_loop; // cannot convert a 'ENTITY*' to a
>> 'loop*'
>> // conversion from a virtual base
>> class is implied
>
> You need to use dynamic_cast here, and in order to do that, ENTITY or
> entity, whichever is the real class, needs to have at least one virtual
> function.
>

There are different ways to do it, C++ has a way, without resorting to
lower level languages with the platform runtime.

It is in the C++ FAQ how to deal with the dreaded diamond, I suggest you
read it.

http://www.parashift.com/c++...
http://www.google.com/search?q=diamond&sitesearch=www.par...

In the C++ there is the virtual keyword in the application of the
reinheritance and so on. It defaults the class body's inherited method
from the common ancestor class, they can be casted among the
intermediate types.

Thanks,

Ross F.

Pete Becker

10/28/2008 10:32:00 AM

0

On 2008-10-27 22:08:09 -0400, "Ross A. Finlayson"
<raf@tiki-lounge.com.invalid> said:

> Pete Becker wrote:
>> On 2008-10-27 18:08:43 -0400, Rocketmagnet <hugo.elias@virgin.net> said:
>>
>>> Hi all,
>>>
>>> I have been kind of forced (honestly) into writing a class structure
>>> which contains a Diamond of Death, and I'm not entirely sure what to
>>> do about it.
>>
>> I don't understand. Having a common virtual base class is sometimes an
>> appropriate design. Why do you call it a "Diamond of Death"?
>>
>>> This is a simplified version of my class structure:
>>
>> Simplified to the point of incorrectness, since the code in main
>> (that's what _tmain means, right?) refers to ENTITY but the nearest
>> thing here is entity.
>>
>>>
>>>
>>> class entity
>>> {
>>> public:
>>> entity() {}
>>>
>>> int a;
>>> };
>>>
>>>
>>> class item : public entity
>>> {
>>> public:
>>> item() {}
>>>
>>> int b;
>>> };
>>>
>>>
>>> class loop : public virtual item
>>> {
>>> public:
>>> loop() {}
>>>
>>> int c;
>>> };
>>>
>>>
>>> class path : public virtual item
>>> {
>>> public:
>>> path() {}
>>>
>>> int d;
>>> };
>>>
>>> class test : public path, public loop
>>> {
>>> public:
>>> test() {}
>>>
>>> int e;
>>> };
>>>
>>>
>>>
>>> int _tmain(int argc, _TCHAR* argv[])
>>> {
>>> ENTITY *entity_test = new test();
>>> ENTITY *entity_loop = new loop();
>>>
>>> loop* l = (loop*)entity_loop; // cannot convert a 'ENTITY*' to a
>>> 'loop*'
>>> // conversion from a virtual base
>>> class is implied
>>
>> You need to use dynamic_cast here, and in order to do that, ENTITY or
>> entity, whichever is the real class, needs to have at least one virtual
>> function.
>>
>
> There are different ways to do it, C++ has a way, without resorting to
> lower level languages with the platform runtime.
>
> It is in the C++ FAQ how to deal with the dreaded diamond, I suggest
> you read it.

Thanks for the pointer, but I'm quite familiar with virtual inheritance.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Hugo Elias

10/28/2008 11:44:00 AM

0

Pete Becker wrote:
> On 2008-10-27 18:08:43 -0400, Rocketmagnet <hugo.elias@virgin.net> said:
>
>> Hi all,
>>
>> I have been kind of forced (honestly) into writing a class structure
>> which contains a Diamond of Death, and I'm not entirely sure what to
>> do about it.
>
> I don't understand. Having a common virtual base class is sometimes an
> appropriate design. Why do you call it a "Diamond of Death"?

I didn't know it had another name. What do you call it?


>> This is a simplified version of my class structure:
>
> Simplified to the point of incorrectness, since the code in main (that's
> what _tmain means, right?) refers to ENTITY but the nearest thing here
> is entity.

Whoops! I was just editing it to make it look nicer for the post,
but obviously missed that.


> You need to use dynamic_cast here, and in order to do that, ENTITY or
> entity, whichever is the real class, needs to have at least one virtual
> function.

Thanks Pete! That seems to work now. I'll try it out on the proper code
when I get home.

Many thanks

Hugo

Juha Nieminen

10/28/2008 5:42:00 PM

0

Jeff Schwab wrote:
> Because proponents of languages that don't support multiple inheritance
> properly have gone out of their way to convince everyone how terrible it
> is. This is always a frustrating discussion; nobody can tell you *why*
> it's bad, but they're sure it's a bomb waiting to go off. No exceptions.

Another irritating thing is that because of the "dangers" of diamond
inheritance, these languages forbid multiple inheritance.

Why the heck do they have to forbid multiple inheritance in order to
avoid diamond inheritance? Why not forbid diamond inheritance only?
There are tons of situations where non-diamond multiple inheritance
would be extremely useful, but these languages go ahead and remove this
useful object-oriented tool.

Jeff Schwab

10/28/2008 5:46:00 PM

0

Juha Nieminen wrote:
> Jeff Schwab wrote:
>> Because proponents of languages that don't support multiple inheritance
>> properly have gone out of their way to convince everyone how terrible it
>> is. This is always a frustrating discussion; nobody can tell you *why*
>> it's bad, but they're sure it's a bomb waiting to go off. No exceptions.
>
> Another irritating thing is that because of the "dangers" of diamond
> inheritance, these languages forbid multiple inheritance.
>
> Why the heck do they have to forbid multiple inheritance in order to
> avoid diamond inheritance? Why not forbid diamond inheritance only?
> There are tons of situations where non-diamond multiple inheritance
> would be extremely useful, but these languages go ahead and remove this
> useful object-oriented tool.

I suspect that they avoid MI because of difficulty implementing it,
rather than difficulty using it. Then there has to be a sour grapes
pitch by the language proponents, explaining why you didn't really want
that feature, anyway.

Pete Becker

10/28/2008 5:51:00 PM

0

On 2008-10-28 13:45:55 -0400, Jeff Schwab <jeff@schwabcenter.com> said:

> Juha Nieminen wrote:
>> Jeff Schwab wrote:
>>> Because proponents of languages that don't support multiple inheritance
>>> properly have gone out of their way to convince everyone how terrible it
>>> is. This is always a frustrating discussion; nobody can tell you *why*
>>> it's bad, but they're sure it's a bomb waiting to go off. No exceptions.
>>
>> Another irritating thing is that because of the "dangers" of diamond
>> inheritance, these languages forbid multiple inheritance.
>>
>> Why the heck do they have to forbid multiple inheritance in order to
>> avoid diamond inheritance? Why not forbid diamond inheritance only?
>> There are tons of situations where non-diamond multiple inheritance
>> would be extremely useful, but these languages go ahead and remove this
>> useful object-oriented tool.
>
> I suspect that they avoid MI because of difficulty implementing it,
> rather than difficulty using it.

No, it's because Barbie says "multiple inheritance is hard!"

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Hugo Elias

10/28/2008 7:00:00 PM

0

Juha Nieminen wrote:
> Why the heck do they have to forbid multiple inheritance in order to
> avoid diamond inheritance? Why not forbid diamond inheritance only?
> There are tons of situations where non-diamond multiple inheritance
> would be extremely useful, but these languages go ahead and remove this
> useful object-oriented tool.

That's what I've always wondered! MI is totally useful.

Hugo

Juha Nieminen

10/28/2008 10:53:00 PM

0

Jeff Schwab wrote:
>> Why the heck do they have to forbid multiple inheritance in order to
>> avoid diamond inheritance? Why not forbid diamond inheritance only?
>> There are tons of situations where non-diamond multiple inheritance
>> would be extremely useful, but these languages go ahead and remove this
>> useful object-oriented tool.
>
> I suspect that they avoid MI because of difficulty implementing it,
> rather than difficulty using it.

Is it really so difficult to implement multiple inheritance in a
language and its compilers?

I do understand that diamond inheritance (what C++ implements as
virtual inheritance) can become complicated. However, what makes
multiple inheritance complicated?

And in this context when I say "complicated" I don't mean "it requires
n thousands of complex code to implement compiler support". That's just
technical detail. With "complicated" I mean eg. situations which are
ambiguous and there's no clear "best solution". An example of what I
consider "complicated" is exception throwing (and subsequent stack
unwinding) in C++: This is a very complicated issue, and there is no
clear "best solution" (afaik all solutions have their own little
problems, often related to efficiency and/or code size).