There is a base class A, which is virtual
class A
{
~virtual A() = 0;
};
and more derived classes B, C, D, E…
class B : public A
{
};
class C: public A
{
};
and analogously for other classed D, E… We have a list of A pointers
std::list <A*> a_list;
We remove any element which type is unknown, for example
A *a = a_list.front();
Base on the type of a pointed object we decide, what to do… There more possibilities how to do that:
A) dynamic_cast case
Recasting of a to derived types.
if (dynamic_cast <B*> (a))
{
//do something (but nothing with a)
}
else if (dynamic_cast <C*> (a))
{
//do other (but nothing with a)
}
But the dynamic_cast usage indicates a bad design.
B) Additional attribute
Some aditional attribute, for example an object ID is impelemented;
class A
{
virtual ~A() = 0;
virtual short getID() = 0;
};
class B : public A
{
virtual short getID() {return 1;}
};
class C: public A
{
virtual short getID() {return 2;}
};
So the modified condition
switch ( a->getID())
{
case 1: // do something (but nothing with a)
case 2: // do other (but nothing with a)
}
A note:
We do not perform any action directly with the object, but on the basis of its type we do some different computations.
Questions:
1) Is it the case, when we should avoid dynamic_cast?
2) is there any prefereable solution (may be different to presented)?
Thanks for your help.
According to Item 90 in C++ Coding Standards (Amazon): Avoid type-switching (regardless whether you do it with an
if-elseladder anddynamic_cast, or aswitchstatement withgetID()function). Prefer instead to rely on polymorphism via virtual functionsThe reason is that having an explicit type-switch is hard to maintain and update. If you get a new derived class from
A, you need to update every place where you loop over types. Instead, the compiler will do that automatically for you if you rely on virtual functions.