Избегайте использования dynamic_cast
dynamic_cast<> - дорогостоящая операция. Если множественное наследование не используется, для приведения вниз по иерархии наследования (от базового класса к производному) по возможности применяйте static_cast<>. Для приведения к базовому классу dynamic_cast не нужен; static_cast тоже не нужен - обычно достаточно неявного преобразования.
Пример для:
struct Base {
virtual ~Base() = default;
virtual void foo();
};
struct Derived : Base {
void foo() override;
};
void bar() {
}
Неправильно:
Правильно:
В большинстве случаев, компилятор способен выявлять ошибочное применение dynamic_cast и оптимизирует заменой на static_cast, однако полагаться на ум и смекалку компилятора не следует.
В случае, когда нельзя гарантировать производный тип, рассмотрите вариант с дополнительным полем в базовом классе, например enum, которое сообщает фактический тип экземпляра.
Пример:
enum class Kind { Derived, Other };
struct Base {
Kind kind;
virtual ~Base() = default;
explicit Base(Kind k) : kind(k) {}
};
struct Derived : Base {
Derived() : Base(Kind::Derived) {}
void foo();
};
struct Other : Base {
Other() : Base(Kind::Other) {}
};
void f(Base* b) {
if (b->kind == Kind::Derived)
static_cast<Derived*>(b)->foo();
}