Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

dynamic_cast Fails with Multiple Inheritance

859 views
Skip to first unread message

Aaron Michalk

unread,
Jan 31, 2002, 6:26:01 PM1/31/02
to
I have the following classes:

class A {};
class B : public A {};
class C : public A {};
class D : public B, public C {};

Why does the dynamic_cast in the following code fail?:

D * pD = new D();
B * pB = pD;
A * pA = pB;
dynamic_cast<A*>(pA);

Carl Daniel

unread,
Jan 31, 2002, 6:53:30 PM1/31/02
to
No virtual functions. Dynamic_cast requires that the classes have virtual
functions to work.

Assuming what you've written below is only illustrative & your actual
classes do have virtual functions, and you didn't really mean to
dynamic_cast an A* to A*, then the problem is that A is an ambiguous base of
D. The RTTI machinery knows that the underlying object is of type D, so
dynamic_cast to A is required to fail according to 5.2.7/8 of the C++
standard. You can make A an unambiguous base by changing B & C to use
virtual inheritance of A.

If you really meant to dynamic_cast an A* to A*, this is required to work,
according to 5.2.7/3 of the Standard. If it doesn't, it's a bug.

-cd

"Aaron Michalk" <aaronm...@hotmail.com> wrote in message
news:f164f05.02013...@posting.google.com...

Aaron Michalk

unread,
Jan 31, 2002, 11:02:24 PM1/31/02
to
Of course there are virtual functions. The example I gave is a much
simplified version of a problem I'm working on in a commercial
software product I'm developing. The bottom line is, because of
legacy code elsewhere I want to do a sanity check like the following:

assert(dynamic_cast<A*>(pA));

My assert is failing even though pA is of type A* (and points to an
object of type D). My current workaround is to change the assert to:

assert(dynamic_cast<A*>(pA) || dynamic_cast<B*>(pA));

This is messy and the containing code shouldn't have to know about B.


"Carl Daniel" <cpda...@pacbell.net> wrote in message news:<u6oZBKrqBHA.2332@tkmsftngp03>...

Arnaud Debaene

unread,
Feb 1, 2002, 3:59:00 AM2/1/02
to
"Aaron Michalk" <aaronm...@hotmail.com> a écrit dans le message de news:
f164f05.02013...@posting.google.com...

> I have the following classes:
>
> Why does the dynamic_cast in the following code fail?:
>
> D * pD = new D();
> B * pB = pD;
> A * pA = pB;
> dynamic_cast<A*>(pA);

Use virtual inheritance :
class A{};
class B : virtual public A{};
class C : virtual public A{};
class D : publicB, public C {};

Arnaud
MVP - VC


Jason

unread,
Feb 1, 2002, 5:58:43 AM2/1/02
to
I'd read all of Carls post...

The problem seems to be ur lack of virtual inheritance and thus an
amibiguous cast...as Carl points out.

Aaron Michalk

unread,
Feb 1, 2002, 9:22:17 AM2/1/02
to
"Arnaud Debaene" <adeb...@club-internet.fr> wrote in message news:<OvOGE7vqBHA.460@tkmsftngp04>...

> Use virtual inheritance :
> class A{};
> class B : virtual public A{};
> class C : virtual public A{};
> class D : publicB, public C {};
>
> Arnaud
> MVP - VC

Actually, I wanted to avoid using virtual inheritance because I want
to have an object that behaves like both of the base objects but has
seperate data instances.

Aaron

Carl Daniel

unread,
Feb 1, 2002, 10:08:25 AM2/1/02
to
Actually, it looks to me like it's a bug. 5.2.7/3 says dynamic_cast<T>(v)
succeeds and returns v if the type of v is already T. In this case, it is.
In this case, the runtime check for T being an unambiguous base should not
occur, but I suspect that it is occurring.

(FWIW, the behavior mandated by 5.2.7/3 makes this an "insanity check",
since no runtime inspection of the most-derived object should be performed).

-cd

"Jason" <chastel...@hotmail.com> wrote in message
news:u3nq98wqBHA.2564@tkmsftngp04...

0 new messages