В настоящее время я использую Unreal Engine 4, и мне кажется, что я не могу избежать некоторых бросков.
AController* c = this->GetController();
APlayerController* p = (APlayerController*)c;
Есть ли способ, которым я могу проверить, если c
это PlayerController
прежде чем я сделаю бросок?
Как и многие игровые движки, Unreal Engine скомпилирован без RTTI по соображениям производительности, поэтому dynamic_cast
не будет работать.
Unreal Engine предоставляет собственную альтернативу, просто называемую Cast
, Я не могу найти документацию для этого сейчас, но этот вопрос описывает его использование красиво.
AController* c = this->GetController();
APlayerController* p = Cast<APlayerController>(c);
if (p) {
...
}
AController
также имеет удобный метод CastToPlayerController
который будет делать то же самое:
AController* c = this->GetController();
APlayerController* p = c->CastToPlayerController();
if (p) {
...
}
Если вы уверены, что c
всегда будет APlayerController
затем CastChecked
более эффективно:
AController* c = this->GetController();
APlayerController* p = CastChecked<APlayerController>(c);
...
В отладочных сборках это будет использовать Cast
и бросить assert, если он вернет null; в сборках релизов он разрешается быстро static_cast
,
Если у классов есть хотя бы одна виртуальная функция (скорее всего), вы можете использовать dynamic_cast
:
APlayerController* p = dynamic_cast<APlayerController*>(c);
Это вернет нулевой указатель, если c
на самом деле не правильный тип во время выполнения.
редактировать Помимо хотя бы одной виртуальной функции, dynamic_cast
также требует, чтобы информация о типе времени выполнения (RTTI) была включена в вашей сборке. Обычно это часть языка, но компиляторы могут поддерживать его отключение.