0

I do not quite understand how to downcast. Apparently I can not do it like this...

class myType
{
};

class otherType : public myType
{
};

int main()
{
    myType* obj = new myType;

    otherType* castObj = dynamic_cast<otherType*>(obj);

    delete obj;
}

What am I missing?

Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57
D Maloid
  • 1
  • 3

2 Answers2

0

Some clarification I think, is needed.

when class B is derived from class A, the following holds:

  • a B is an A
  • an A is not necessarily a B

if you are holding a pointer to A, you can check whether it is the A-part of a B by attempting to dynamic_cast to a B. If that cast succeeds, it is because you were actually pointing to the B's A interface. If the cast does not succeed then the A-like thing you were pointing at was not actually a B.

So:

struct A {
    virtual ~A();
};        // a base class

struct B : A {};    // a B is an A but an A is not necessarily a B

A* pa = new A;
// pa is pointing to an A

B* pb = dynamic_cast<B*>(pa);
// pb will now be NULL because this cast will have failed.
// Remember, a B *is an* A, but an A *is not necessarily a* B

delete pa;

// try again...
pa = new B;
// pa points to the A-part of a B, so

pb = dynamic_cast<B*>(pa);
// pb now points to the same object, but has access to all the methods on the B interface

delete pb;
// clean up
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
0

This is how I like to explain this to my girlfriend:

Something being a car means that it definitely has wheels.

Something having wheels does not necessarily make it a car.

Say we have classes:

class A

and

Class B: public A

The Class B surely has all the traits of the Class A and probably some more, but we can always safely convert it (cast it) to the Class A by simply "removing" all the additional things it carries, which is not true the other way around: we cannot be certain that the Class A will have the same traits as the class you're trying to cast it to, in this case Class B. This is why you have to use the dynamic cast, to inform the compiler that you're aware of the risk this ensues.

If the cast is successful, dynamic_cast returns a value of type new_type. If the cast fails and new_type is a pointer type, it returns a null pointer of that type. If the cast fails and new_type is a reference type, it throws an exception that matches a handler of type std::bad_cast.

Vucko
  • 7,371
  • 2
  • 27
  • 45
  • I can offer even better analogies: Something being a **dog**, definitely makes it an **animal**. Something being an **animal** does not necessarily make it a **dog** – Vucko Mar 25 '16 at 21:14
  • I have millions of them, but you get the point. And now I'm talking to myself :-D – Vucko Mar 25 '16 at 21:15