如何安全地向下转换USTRUCT

时间:2019-05-11 13:43:45

标签: c++ reflection polymorphism unreal-engine4

虚幻引擎支持通过UObject*Cast<T>向下广播custom implementation of dynamic_cast<T*>

向下转换USTRUCT对象时,两种方法均无效:

  1. Cast<T>的方法不支持转换为UScriptStructs
  2. UE4无需RTTI即可编译(例如,为cl.exe设置了/GR-),UE4使用实现的dynamic_cast<T*>来指向USTRUCT的指针。因此,编译器将抛出C4541(请参见下面的示例)。

UE4.22中是否存在一种使用UE4的反射系统安全地 下传USTRUCT的方法(因此,当static_cast<T*>等不是选项时)?

如果不是,那么为什么UE4不支持通过Cast函数下传USTRUCT?例如。应该引用它们还是与Blueprint相关的原因?


在UE4项目中使用的示例(2):

#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 个答案:

答案 0 :(得分:1)

  

UE4.22中是否存在一种使用UE4的反射系统安全地下播USTRUCT的方法(因此,当无法选择static_cast等时)?

我知道这不是一个理想的解决方案,可能不适合您的情况,但是如果您不想使用裸override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) if navigationController?.isNavigationBarHidden ?? false { navigationController?.setNavigationBarHidden(false, animated: false) tabBarController?.tabBar.isHidden = false } } ,则可以提供一个模板函数来进行强制类型转换并添加一个{{1 }}中插入static_cast会导致编译时错误,导致强制转换失败。

static_assert
  

为什么UE4的Cast函数不支持下播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); } 工作所需的反射没有提供给它们。

在使用指向USTRUCTs的指针时要小心,因为它们不仅不受反射的支持,而且也不受垃圾收集器,序列化器,UI等的支持。您必须知道在处理它们时在做什么。

答案 1 :(得分:0)

根据虚幻论坛中的post,在虚幻中没有UStruct的动态投稿。我不确定为什么,但是根据此post,虚幻的反射系统似乎不支持指向UStruct类型的对象的指针。

这里的选项包括C样式强制转换,以及您提到的静态强制转换。但是,这两种方法都不是那么安全,但当您知道要传递给转换的对象是转换中指定的类型时,通常静态转换是安全的。

C样式转换:

auto o = (MyStructDerived*) lvaluePtr;

静态转换:

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