Использование dynamic_cast само по себе не является плохой практикой.Это плохая практика - использовать ее не по назначению, то есть там, где это действительно не нужно.
Это также плохая практика использовать его следующим образом:
(dynamic_cast<Derived1*>(b))->SpecialD1DoSomething();
Причина: dynamic_cast (b) может возвращать NULL.
При использовании dynamic_cast вы должны бытьочень осторожно, поскольку не гарантируется, что b на самом деле имеет тип Derived1, а не Derived2:
void GenericFunction(Base* p)
{
(dynamic_cast<Derived1*>(b))->SpecialD1DoSomething();
}
void InitiallyImplementedFunction()
{
Derived1 d1;
GenericFunction(&d1); // OK... But not for long.
// Especially, if implementation of GenericFunction is in another library
// with not source code available to even see its implementation
// -- just headers
}
void SomeOtherFunctionProbablyInAnotherUnitOfCompilation()
{
Derived2 d2;
GenericFunction(&d2); // oops!
}
Вы должны проверить, действительно ли dynamic_cast успешен.Есть два способа сделать это: проверить это до и после приведения.Перед приведением вы можете проверить, является ли указатель, который вы пытаетесь привести, именно тем, который вы ожидаете через RTTI:
if (typeid(b) == typeid(Derived1*))
{
// in this case it's safe to call the function right
// away without additional checks
dynamic_cast<Derived1*>(b)->SpecialD1DoSomething();
}
else
{
// do something else, like try to cast to Derived2 and then call
// Derived2::SpecialD2DoSomething() in a similar fashion
}
Проверка этого постфактум на самом деле немного проще:
Derived1* d1 = dynamic_cast<Derived1*>(b);
if (d1 != NULL)
{
d1->SpecialD1DoSomething();
}
Я бы также сказал, что пытаться сохранять набор текста при программировании на C ++ - плохая практика.В C ++ есть много функций, которые кажутся вполне подходящими для того, чтобы набирать их короче (т. Е. Дает вам ощущение «что NULL здесь никогда не случится»), но оказывается, что задница после отладки - это боль в заднице.;)