Проверьте, является ли A подклассом B?

В настоящее время я использую Unreal Engine 4, и мне кажется, что я не могу избежать некоторых бросков.

AController* c = this->GetController();
APlayerController* p = (APlayerController*)c;

Есть ли способ, которым я могу проверить, если c это PlayerController прежде чем я сделаю бросок?

7

Решение

Как и многие игровые движки, 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,

5

Другие решения

Если у классов есть хотя бы одна виртуальная функция (скорее всего), вы можете использовать dynamic_cast:

APlayerController* p = dynamic_cast<APlayerController*>(c);

Это вернет нулевой указатель, если c на самом деле не правильный тип во время выполнения.

редактировать Помимо хотя бы одной виртуальной функции, dynamic_cast также требует, чтобы информация о типе времени выполнения (RTTI) была включена в вашей сборке. Обычно это часть языка, но компиляторы могут поддерживать его отключение.

7

По вопросам рекламы [email protected]