【问题标题】:How to safely downcast USTRUCTs如何安全地向下转换 USTRUCT
【发布时间】:2019-09-29 03:33:33
【问题描述】:

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

当向下转换USTRUCT 对象时,两种方法都不起作用:

  1. Cast<T> 的方法不支持转换为UScriptStructs
  2. UE4 在没有 RTTI 的情况下编译(例如,为 cl.exe 设置了/GR-),并且 UE4 使用实现的dynamic_cast<T*> 指向USTRUCTs 的指针。因此编译器会抛出C4541(参见下面的示例)。

在 UE4.22 中是否有一种方法可以安全地使用 UE4 的反射系统向下转换 USTRUCTs(所以当 static_cast<T*> 等不是一个选项时)?

如果不是,那为什么 UE4 不支持通过 Cast 函数向下转换 USTRUCTs?例如。它们不应该被引用还是蓝图相关的原因?


(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
}

【问题讨论】:

    标签: c++ reflection polymorphism unreal-engine4


    【解决方案1】:

    UE4.22 中是否有一种方法可以使用 UE4 的反射系统安全地向下转换 USTRUCT(所以当 static_cast 等不是一个选项时)?

    我知道这不是一个理想的解决方案,可能不适合您的情况,但如果您不想使用裸 static_cast,您可以提供一个模板函数来执行转换并添加一个 static_assert 和 @ 987654323@ 里面得到一个编译时错误是强制转换失败。

    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 的 Cast 函数不支持向下转换 USTRUCTs

    这是因为结构在虚幻引擎中应该是轻量级实体,因此反射(Cast 工作所必需的)未以最小形式提供

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

    【讨论】:

      【解决方案2】:

      根据 Unreal 论坛中的 post,在 Unreal 中没有为 UStruct 工作的动态演员表。我不知道为什么,但根据post,虚幻的反射系统似乎不支持指向UStruct 类型对象的指针。

      您在此处的选项包括 C 样式转换,就像您提到的那样,静态转换。但是,任何一个选项都不是那么安全,除了当您知道传递给强制转换的对象是强制转换中指定的类型时,静态强制转换通常是安全的。

      C 风格的演员表:

      auto o = (MyStructDerived*) lvaluePtr;
      

      静态转换:

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

      【讨论】:

        【解决方案3】:

        您还可以通过检查结构类型是否是您要转换到的类型的子类型以及您要转换到的类型是结构类型的子级来检查结构转换的安全性。如果两个条件都为真,则它们是同一类型。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-06-14
          • 1970-01-01
          • 1970-01-01
          • 2012-08-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多