Ответ 1
Используйте static_cast
. Если вы знаете, что ваш Base*
указывает на Derived
, используйте static_cast
. dynamic_cast
полезен, когда он может указывать на производный.
Предположим, что мне предоставлена библиотека С++, полная наследования. Мне предоставляется функция Base*
в функции, когда я знаю, что она фактически указывает на объект Derived
и Derived
наследует Base
. Но я не знаю, какое это наследство (public/protected/private). Я также не знаю, есть ли виртуальная функция в иерархии.
Учитывая эту ситуацию, , не глядя на исходный код/документацию из Base
и Derived
, какой листинг следует использовать? Или я должен сначала проконсультироваться с кодом/документацией, чтобы убедиться в полиморфизме?
Фон
Я пишу changeEvent
функцию QMainWindow
в Qt 4.7. Функция changeEvent
принимает QEvent*
, которую я могу передать другому типу, зная QEvent::type()
. Мне было интересно, следует ли использовать static_cast
или dynamic_cast
.
Спасибо.
Используйте static_cast
. Если вы знаете, что ваш Base*
указывает на Derived
, используйте static_cast
. dynamic_cast
полезен, когда он может указывать на производный.
Если вы сомневаетесь, вы должны предпочесть dynamic_cast
. Это может быть медленнее, но вы, вероятно, не заметите разницу.
Если вам нужна скорость, используйте следующий фрагмент:
template <typename Derived, typename Base>
Derived safe_static_cast(Base b)
{
assert((void*)dynamic_cast<Derived>(b) && "safe_static_cast failed!");
return static_cast<Derived>(b);
}
Или что-то эквивалентное.
Идея заключается в том, что в сборках отладки он проверяет, действительно ли это было так, как вы думали, и выпускает сборки... ну, все уже проверено, не так ли?
От MSDN -
В общем случае вы используете static_cast, когда хотите преобразовать числовые типы данных, такие как перечисления в int или ints, в float, и вы уверены в типах данных, участвующих в преобразовании. Преобразования static_cast не так безопасны, как преобразования dynamic_cast, потому что static_cast не проверяет тип выполнения во время выполнения, а dynamic_cast. Ошибка dynamic_cast для двусмысленного указателя не будет выполнена, а static_cast вернется, как будто ничего не случилось; это может быть опасно. Хотя конверсии dynamic_cast более безопасны, dynamic_cast работает только с указателями или ссылками, а проверка типа времени выполнения является накладными расходами.
Для получения дополнительной информации ознакомьтесь с этой ссылкой