2
votes

In C++ primer(5th) 19.2.1 about dynamic_cast. It says, for dynamic_cast<type*>(e) to be successful,

the type of e must be either a class type that is publicly derived from the target type, a public base class of the target type, or the same as the target type

However, for the following code:

class B{
  public:
    virtual ~B(){}
};

class D : public B{};

B *pb = new B;
D *pd = dynamic_cast<D*>(pb);
if(pd == 0) cout << "err" << endl;

The output is "err". But the type of pb is a public base class of type D.

Is this a mistake in C++ primer(5th)? Or do I just misunderstand these words?

2
pb has to point to a D to begin with. You have a B.StoryTeller - Unslander Monica
You misunderstood the words.juanchopanza
@StoryTeller: Since pb has type B*, it cannot point at anything other than a B.Kerrek SB
@KerrekSB - D is-a B however :PStoryTeller - Unslander Monica

2 Answers

4
votes

The type of pb is indeed a public base class of D, but the object that pb points to is not the base subobject of any object of type D. The dynamic cast detects this and returns null.

If indeed you did attempt to cast the pointer to a base subobject of a D object, you would get the (non-null) pointer to the D object:

D obj;
B *pb = &obj;   // points at subobject

assert(&obj == dynamic_cast<D*>(pb));

The requirement that you've cited is merely a static requirement that allows you to use the dynamic cast at all -- but it does not describe the result of using the cast. That's described later on.

2
votes

dynamic_cast can be used as a tool to detect if an object is derived from another one or not, in the code you've written, the answer is NO, so you got a null. By

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

You're down-casting a base to a derived, and it is reverse of what the documet is saying. Of course you can have below if pb points to an extact D*:

B *pb = new D; // <--- It is a `D`
D *pd = dynamic_cast<D*>(pb);