The title is a bit vague because I don't actually know what this problem is called. I will give an example of the problem. Below is a simple shape class heirarchy. I have left a lot necessary things out I know. It is just an example:
class CShape
{
virtual void dummy()=0;
};
class CSquare : public CShape
{
void setRadius();
}
class CCircle : public CShape
{
..
}
Okay now say that I have a container of shape pointers and I fill it with various shapes:
vector<CShape*> shapes;
shapes.push_back(new CSquare());
shapes.push_back(new CCircle());
Now here is the problem: What if I want to iterate through the shapes in that container and call the setRadius method on each circle? Ie:
for (int i=0;i<shapes.size();i++)
{
shapes->setRadius();
}
The problem is that not all the shapes have to be circles. Some might be squares. At run time I do not know. If one of the shapes is a square, then the call to setRadius() could fail. There are several options I can think of getting round this problem, and I was just wondering if anyone had any ideas.
1st solution
Abstract class CShape defines a virtual member function called ID. Derived classes must implement this function to return a unique ID. Therefore I could do this:
for (int i=0;i<shapes.size();i++)
{
if (shapes.ID() == CIRCLE)
shapes->setRadius();
}
2nd solution
Use RTTI (which I only just found out existed) to determine the type of shape:
for (int i=0;i<shapes.size();i++)
{
if (CCircle*cptr = dynamic_cast <CCircle*>(shapes))
shapes->setRadius();
}
3rd solution
Implement an empty setRadius function in the base CShape class, it is then optional whether derived classes override it, but at least it can be called by all shapes without failing.
class CShape
{
virtual void dummy()=0;
void setRadius(); //this class will be implemented as empty
};
for (int i=0;i<shapes.size();i++)
{
shapes->setRadius();
}
This is my least favorite method as it just seems wrong to me. Not all shapes have a radius property, so in my opinion it shouldn't be part of a base shape class.
Perhaps someone has a better method of doing this? (this is what I hope). Just to note that the generic shape container is required, it is not an option to have seperate containers for each type of shape.
Wouldn't it be nice if when calling setRadius() on an object, if that method didn't exist on that class then it was just not called?
Thanks for reading