Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ inheritance downcasting

Tags:

I have my base class as follows:

class point    //concrete class
{
 ...    //implementation
}

class subpoint : public point  //concrete class
{
...     //implementation
}

How do I cast from a point object to a subpoint object? I have tried all three of the following:

point a;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;
subpoint b = (subpoint)a;

What is wrong with these casts?

like image 822
CodeKingPlusPlus Avatar asked Aug 07 '12 22:08

CodeKingPlusPlus


2 Answers

How do I cast from a point object to a subpoint object?

You can't; unless either point has a conversion operator, or subpoint has a conversion constructor, in which case the object types can be converted with no need for a cast.

You could cast from a point reference (or pointer) to a subpoint reference (or pointer), if the referred object were actually of type subpoint:

subpoint s;

point & a = s;
subpoint & b1 = static_cast<subpoint&>(a);
subpoint & b2 = dynamic_cast<subpoint&>(a);

The first (static_cast) is more dangerous; there is no check that the conversion is valid, so if a doesn't refer to a subpoint, then using b1 will have undefined behaviour.

The second (dynamic_cast) is safer, but will only work if point is polymorphic (that is, if it has a virtual function). If a refers to an object of incompatible type, then it will throw an exception.

like image 89
Mike Seymour Avatar answered Sep 20 '22 18:09

Mike Seymour


The purpose of a dynamic cast is to "check at run time if an object is of a certain type in the hierarchy". So now let's look at what you have:

  1. You have a point object. Not a subpoint.
  2. You're asking a dynamic cast if the object is a subpoint. It's not.
  3. Because its not a subpoint, dynamic_cast fails - its way of telling you that the object is not the type you're trying to cast it to.

By contrast, this would have worked:

subpoint c;
point *a = &c;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;
like image 34
Carl Avatar answered Sep 18 '22 18:09

Carl