Re: Why I cann't use dynamic_cast to convert from a non-polymorphic class

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



On Mon, 9 Mar 2009 00:03:24 -0700 (PDT), wuguangwen734@xxxxxxxxxxx wrote:

Here is the class hierarchy:
class A{};
class B:public A {};
class C:public A{};
class D:public B, public C{};

Then, I compiled the following code,
B* pb = new D;
D* pd = dynamic_cast<D*>(pb);

and got the compiler error C2683: 'cast' : 'type' is not a polymorphic
type.

While I changed the definition of class B as:
class B:public A {void virtual f(){}};

the compiler didn't complain any more.

What is the difference? Why the compiler insist on requiring the the
being casted type polymorphic?

Because them's the rules.

Dose the existence of multiple
inheritance make difference in this question?

No.

For this dynamic_cast usage, the type of the source pointer or reference
must be of a class that has at least one virtual function. If it does not
have a virtual function, it is not a polymorphic type, and within the
conceptual model of C++, using dynamic_cast to query the type doesn't make
sense. Practically speaking, it is common for a compiler to attach a
pointer to RTTI data structures to a class's vtbl, and since only classes
that have at least one virtual function have a vtbl, i.e. polymorphic
classes, that's sort of a trivial reason for the requirement.

To understand this more completely, consider what is known in the
statement:

D* pd = dynamic_cast<D*>(pb);

The compiler knows that pb has the type B* and that B is not polymorphic.
In order to determine if pb points to a base class subobject of a D object,
it has to look up that information somehow. In C++, there is no general
..NET style reflection capability, and objects of non-polymorphic types are
just the bits specified in the class definition. Thus, for the dynamic_cast
to be possible when B isn't polymorphic, the program would have to track
all objects of that type in some sort of registry that maps object
addresses to type information. That's totally against the spirit of C++,
and it isn't done. OTOH, when you give B a virtual function and make it
polymorphic, you're giving the compiler the latitude to do whatever it
needs to enable the behavior expected of polymorphic types. In particular,
the layout of B objects can have extra data to support polymorphism, and
that usually comes in the form of a vptr, or a pointer to the vtbl or
virtual function table for the class. The vtbl is obviously a good place to
add on a pointer to RTTI data structures, and that's what Stroustrup
described in his early writing on the subject. So, when B is polymorphic,
dynamic_cast can get at B's vtbl when passed a B* or B&, thanks to the B
object's vptr, and it can use the RTTI structures pointed to by the vtbl to
determine if the B is part of a D object.

--
Doug Harrison
Visual C++ MVP
.



Relevant Pages

  • Re: Interview questions
    ... How did your compiler know where to get the entry point for Hello? ... > without calling a wrapper function. ... *without* any public definition of the virtual function table. ... The programmer is playing the role of the compiler. ...
    (comp.lang.cpp)
  • Re: calling virtual function from base class
    ... int main ... the function "EatPoo" is not virtual. ... when you make a call to "EatPoo", when the compiler is compiling the code it ... virtual function, and as such, when you call it, a "look-up" IS performed. ...
    (comp.lang.cpp)
  • Re: why is a superclass allowed to access protected methods of a subclass?
    ... > me that fact that the compiler allows access to a protected method on an ... surprised to learn of the package visibility of protected methods. ... I think that the compiler has to behave the way it does to accommodate ... polymorphism, while doing what it can to enforce encapsulation. ...
    (comp.lang.java.programmer)
  • Re: When is a static data member defined?
    ... >> After examining the object files emitted by the compiler for various ... > to implement a language in general. ... > language definition: virtual function mechanism implementation. ... then our deductions constitute mathematics. ...
    (comp.lang.cpp)
  • Re: Interview questions
    ... And here's the assembly code my compiler generates for Test: ... > in the virtual function table. ... layout from the class definition, ... Therefore, things like vtables and virtual calls, which a C++ ...
    (comp.lang.cpp)