Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Downcasting to Derived Class based off Variable

Suppose I have a base class "Shape", and derived classes "Triangle", "Square", and "Circle". A member of "Shape" is an int "shapeType".

If shapeType==1, then it's a triangle. If shapeType==2, then it's a square. If shapeType==3, then it's a circle.

I'm interested in knowing given I have just a "Shape" object that was once a derived-object, if there is a way to "dynamically" down-cast to the proper derived class by using the shapeType value.

I know I can do a hard-code switch statement, roughly like:

Triangle* t;
Square* s;
Circle* c;

switch (shape->shapeType) {
case 1:
   t = (Triangle*)shape;
case 2: 
   ...
}

However, the above requires me to make a pointer of EVERY derived class possibility. I am wondering if there is a way to do this without hard-coding every class, but instead somehow determine the class type map where the key is the shapeType and the value is the class type.

like image 638
rkeeler78 Avatar asked Jun 24 '11 17:06

rkeeler78


1 Answers

If they've virtual functions, then use dynamic_cast:

t = dynamic_cast<Triangle*>(shape);
if ( t )
{
     //use t
}

But take a note: you should try defining the classes and virtual functions in such a way that you would hardly need to use dynamic_cast. Prefer well-defined interface, and polymorphism, in general.

Here is one example,

class Shape
{
   public:
     virtual ~Shape() {} //destructor must be virtual - important!
     virtual double Area() const = 0;
};

class Triangle : public Shape
{
   public:
     Triangle(double a, double b, double c);
     virtual double Area() const 
     {
         //calculate area and return it!
     }
};

Shape *s = new Triangle(10, 20, 30);
double aread = s->Area(); //calls Triangle::Area()

No need to use shapeType variable.

like image 73
Nawaz Avatar answered Sep 19 '22 12:09

Nawaz