Как безопасно убить USTRUCT - PullRequest
2 голосов
/ 11 мая 2019

Unreal Engine поддерживает понижение UObject* через Cast<T> и через пользовательскую реализацию dynamic_cast<T*>.

При понижении USTRUCT объектов оба метода не работают:

  1. Методы Cast<T> не поддерживают преобразования в UScriptStructs.
  2. UE4 компилируется без RTTI (например, /GR- установлено для cl.exe), а UE4 использует dynamic_cast<T*> реализации для указателей на USTRUCT s. Поэтому компилятор выдает C4541 (см. Пример ниже).

Есть ли способ в UE4.22 для безопасно downcast USTRUCT s с использованием системы отражения UE4 (поэтому, когда static_cast<T*> и т. Д. Не вариант)?

Если нет, то почему UE4 не поддерживает понижение USTRUCT s с помощью функций Cast? Например. не следует ли на них ссылаться или причины, связанные с Blueprint?


Пример для (2), используется в проекте UE4:

#pragma once
#include "CoreMinimal.h"

USTRUCT()
struct MyStructBase
{
    virtual ~MyStructBase() = default;
};

USTRUCT()
struct MyStructDerived : public MyStructBase
{};

void TestFunc()
{
    auto lvalue = MyStructBase{};
    auto lvaluePtr = &lvalue;
    auto o = dynamic_cast<MyStructDerived*>(lvaluePtr); // cl.exe throws C4541
}

Ответы [ 2 ]

2 голосов
/ 13 мая 2019

Есть ли в UE4.22 метод безопасного понижения USTRUCT с использованием системы отражения UE4 (поэтому, когда static_cast и т. Д. Не вариант)?

Я знаю, что это не идеалрешение и может не подходить для вашего случая, но если вы не хотите использовать голый static_cast, вы можете предоставить шаблонную функцию, которая выполняет приведение и добавить static_assert с TIsDerivedFrom внутри, чтобы получить ошибку времени компиляциибыло ли приведение к сбою.

template<typename T, typename U>
T* CastStruct(U* base)
{
    static_assert(TIsDerivedFrom<T, U>::IsDerived, "Type T has to be derived from U.");
    return static_cast<T*>(base);
}

почему UE4 не поддерживает понижение USTRUCTs своими функциями приведения?

Это потому, что структуры должны быть легковеснымисущности в Unreal Engine и, следовательно, отражение - которое требуется для работы Cast - для них не предусмотрено.

Будьте осторожны при использовании указателей на USTRUCTs, поскольку они не только не поддерживаются отражением, но итакже сборщик мусора, сериализаторы, пользовательский интерфейс и т. д. При работе с ними вы должны знать, что вы делаете.

0 голосов
/ 11 мая 2019

Согласно этому сообщению на форумах Unreal, в Unreal не существует рабочего динамического приведения для UStruct.Я не уверен почему, но похоже, что указатели на объекты типа UStruct не поддерживаются системой отражения Unreal, согласно этому post .

Здесь вы можете выбрать приведение в стиле C и, как вы упомянули, статическое приведение.Однако любой из этих вариантов не так уж безопасен, за исключением того, что статическое приведение обычно безопасно, если вы знаете, что объект, передаваемый в приведение, имеет тип, указанный в приведении.

Приведение в стиле C:

auto o = (MyStructDerived*) lvaluePtr;

Статический актерский состав:

auto o = static_cast<MyStructDerived*>(lvaluePtr);
...