Используйте `dynamic_cast` к типу указателя, когда отсутствие требуемого класса считается допустимой альтернативой
Причина
Преобразование dynamic_cast позволяет проверить, указывает ли указатель на полиморфный объект, имеющий данный класс в своей иерархии. Поскольку при неудаче просто возвращается нулевое значение, это можно проверить во время выполнения. Это позволяет писать код, выбирающий альтернативные пути в зависимости от результатов.
Сравните с C.147, где неудача является ошибкой, и не должен использоваться для условного выполнения.
Пример
Приведённый ниже пример описывает функцию add класса Shape_owner, принимающего во владение созданные объекты Shape. Объекты также сортируются по представлениям согласно их геометрическим атрибутам. В этом примере Shape не наследует от Geometric_attributes. Это делают только его подклассы.
void add(Shape* const item)
{
// Владение всегда передаётся
owned_shapes.emplace_back(item);
// Проверяем Geometric_attributes и добавляем фигуру в ни одно/одно/некоторые/все представления
if (auto even = dynamic_cast<Even_sided*>(item))
{
view_of_evens.emplace_back(even);
}
if (auto trisym = dynamic_cast<Trilaterally_symmetrical*>(item))
{
view_of_trisyms.emplace_back(trisym);
}
}
Примечания
Неудача при поиске требуемого класса заставит dynamic_cast вернуть нулевое значение, а разыменование нулевого указателя приведёт к неопределённому поведению. Поэтому результат dynamic_cast всегда должен обрабатываться так, как будто он может содержать нулевое значение, и проверяться.
Контроль
- (Сложный) Если результат
dynamic_castуказателя не проверяется на null, предупреждать при разыменовании указателя.