-1

Base * pba = new Derived; Base * pbb = new Base;

Even though both are pointers of type Base*, pba actually points to an object of type Derived, while pbb points to an object of type Base. Therefore, when their respective type-casts are performed using dynamic_cast, pba is pointing to a full object of class Derived, whereas pbb is pointing to an object of class Base, which is an incomplete object of class Derived.

What does an incomplete object of class Derived means?

2 Answers2

3

Base does not have member variables and/or member methods declared in Derived, and is therefore incomplete; As this is frequently the case, dynamic_cast forbids the casting of an actual parent type to its derived type.

Simply put: Derived is a Base, but Base is not a Derived, and dynamic_cast will not cast something into something it is not. That requires reinterpret_cast and is a recipe for undefined behavior.

Side note:

If you are going to ask questions about code examples from cplusplus.com you should link them.

I found your snippet here http://www.cplusplus.com/doc/tutorial/typecasting/ under dynamic cast.

Tzalumen
  • 652
  • 3
  • 16
0

There are declarations of types, and definitions of types.

If you declare a type, it might not be actually defined:

// declare X
class X;

// define X 
class X { 
  int value;
};

You may create a pointer to a type that has been only declared, but you may not instantiate an object if it is ONLY declared--it must also be defined. (Definitions are also declarations.)

Also, while inside the definition of a type, the type itself is still incomplete. Only after the full definition has completed (think the closing } of the class) then it is a complete type and you may instantiate it.

This prevents things like declaring an object to have an instance of itself in itself.

class Bad {
   Bad other; // Invalid: Bad is still an incomplete type
};

class Good {
   Good * other; // just a pointer is ok, doesn't need type info
};

Of course, if you have a pointer to an incomplete type, you still are not allowed to dereference it, or call through it, because the compiler doesn't know anything about what's there. If you use the pointer as more than storing an address, you still must have the full definition.

So what's the big fuss? Why declare incomplete types?

In a header, if you only need a pointer to an object, you can avoid including that object's header. That means the file does not depend on the implementation, and anyone modifying the object header will NOT require your code to recompile. If you include the header of another object, you (and anyone that includes you) will need to recompile anytime that header changes. If it's a gratuitous include, it's a slowdown to compile times and a nastier dependency graph in your codebase. So utilizing incomplete types is beneficial, even if it adds a small level of complexity.

Chris Uzdavinis
  • 6,022
  • 9
  • 16