【问题标题】:How to instantiate an implementation of interface?如何实例化接口的实现?
【发布时间】:2016-10-04 07:40:30
【问题描述】:

我有两个属性:

UPROPERTY()
TScriptInterface<ICoordinateSystem> CoordinateSystem;

UPROPERTY(EditAnywhere)
TSubclassOf<UCoordinateSystem> CoordinateSystemType;

如何实例化 CoordinateSystemType 并将结果存储到 CoordinateSystem?我尝试过不同的方法,比如

CoordinateSystem = NewObject<ICoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType); 
CoordinateSystem = NewObject<UCoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType);
CoordinateSystem = Cast<ICoordinateSystem>(NewObject<UCoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType));

但是它们都没有编译说它不能在 NewObject 或 TScriptInterface = 运算符中将 UObject* 转换为 ICoordinateSystem* 或 ICoordinateSystem* 转换为 UObject*。 我在 UE 4.11 和 4.12 中尝试过

编辑:代码

CoordinateSystem = Cast<ICoordinateSystem>(NewObject<UCoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType));

我得到错误:

1>------ Build started: Project: UE44X, Configuration: DebugGame_Game x64 ------
1>  Creating makefile for UE44X (working set of source files changed)
1>  Parsing headers for UE44X
1>    Running UnrealHeaderTool "F:\UE4\UE44X 4.12\UE44X.uproject" "F:\UE4\UE44X 4.12\Intermediate\Build\Win64\UE44X\DebugGame\UE44X.uhtmanifest" -LogCmds="loginit warning, logexit warning, logdatabase error" -Unattended -WarningsAsErrors -installed
1>  Reflection code generated for UE44X in 4,8843075 seconds
1>  Performing 2 actions (4 in parallel)
1>  UE44XGameMode.cpp
1>C:\Program Files (x86)\Epic Games\4.12\Engine\Source\Runtime\CoreUObject\Public\UObject\ScriptInterface.h(150): error C2664: 'void FScriptInterface::SetObject(UObject *)': cannot convert argument 1 from 'ICoordinateSystem *' to 'UObject *'
1>  C:\Program Files (x86)\Epic Games\4.12\Engine\Source\Runtime\CoreUObject\Public\UObject\ScriptInterface.h(150): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>  F:\UE4\UE44X 4.12\Source\UE44X\UE44XGameMode.cpp(26): note: see reference to function template instantiation 'InterfaceType &TScriptInterface<InterfaceType>::operator =<To>(UObjectType *)' being compiled
1>          with
1>          [
1>              InterfaceType=ICoordinateSystem,
1>              To=ICoordinateSystem,
1>              UObjectType=ICoordinateSystem
1>          ]
1>  F:\UE4\UE44X 4.12\Source\UE44X\UE44XGameMode.cpp(26): note: see reference to function template instantiation 'InterfaceType &TScriptInterface<InterfaceType>::operator =<To>(UObjectType *)' being compiled
1>          with
1>          [
1>              InterfaceType=ICoordinateSystem,
1>              To=ICoordinateSystem,
1>              UObjectType=ICoordinateSystem
1>          ]
1>ERROR : UBT error : Failed to produce item: F:\UE4\UE44X 4.12\Binaries\Win64\UE44X-Win64-DebugGame.pdb
1>  Total build time: 11,90 seconds
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.MakeFile.Targets(37,5): error MSB3075: The command ""C:\Program Files (x86)\Epic Games\4.12\Engine\Build\BatchFiles\Build.bat" UE44X Win64 DebugGame "F:\UE4\UE44X 4.12\UE44X.uproject" -waitmutex" exited with code 5. Please verify that you have sufficient rights to run this command.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

【问题讨论】:

  • 请提供准确的错误信息。
  • 它显示:pastebin.com/6BDcmX6W 代码:CoordinateSystem = Cast&lt;ICoordinateSystem&gt;(NewObject&lt;UCoordinateSystem&gt;((UObject *) GetTransientPackage(), *CoordinateSystemType));

标签: c++ types unreal-engine4


【解决方案1】:

接口通常被视为声明函数的类,但这些函数通常在子类中实现。

在 UE4 中,IInterface 不是 UObject。您需要创建一个派生自您的接口的类。

class MyClass : public UObject, public ICoordinateSystem
{
    //Overrides functions from ICoordinateSystem
    ....
};

您将能够实例化 MyClass。要获取 MyClass 的 CoordinateSystem 的句柄,请使用 Cast 模板...

MyClass* myClassInstance;
....
ICoordinateSystem* coordinateInterface = Cast<ICoordinateSystem>(myClassInstance);

希望本文能帮助阐明如何使用接口: https://wiki.unrealengine.com/Interfaces_in_C%2B%2B

【讨论】:

  • InterfaceCast 已弃用。那么使用接口有什么意义呢?如果你是对的,你没有理由不使用抽象类,因为无论如何都不可能实例化带有 2+ 个接口的类。
  • 对已弃用的演员表进行了更正。您仍然可以实例化实现接口的对象。接口的用途类似于组件,您可以在其中声明可能在多个互不相关的类中使用的函数。一个有用的例子是您可以声明一个函数,该函数需要一个指向该接口的指针。函数本身并不关心它是什么类型的对象,它只关心它实现了从该接口声明的函数。
  • 所以你的意思是没有办法通过属性获取接口实现类型并将其实例化为 TScriptInterface 属性?
  • 恐怕我没有完全理解你所说的获取接口实现类型是什么意思。我猜你想获得一个类似于 UClasses 的接口类的句柄,然后使用它的引用来实例化该特定类型的对象。例如:GetWorld()->SpawnActor(UCoordinateSystem::StaticClass())。附属于子类的接口在编译时进行评估,在运行时不能修改。这就像试图在运行时更改对象的超类。如果是这样的话,我相信组件就是您正在寻找的东西。
  • 不,我不是。例如:我有一些接口IMyInterface 和一些类,如UMyClass : UObject, IMyInterface。我想通过TSubclassOf&lt;SomeType&gt; 甚至UClass 之类的属性获取任何这些类的类型并实例化它。然后我想将它存储在某个变量中以备后用。在上一条评论中,我问过是否只能使用抽象类而不是接口。
猜你喜欢
  • 2014-03-12
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
相关资源
最近更新 更多