如何实例化接口的实现?

3

我有两个属性:

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 ==========

请提供精确的错误信息。 - Jesper Juhl
它显示了这个:http://pastebin.com/6BDcmX6W,用于代码:`CoordinateSystem = Cast<ICoordinateSystem>(NewObject<UCoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType));` - Vasja Filippov
1个回答

0

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

在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已被弃用。那么使用接口的意义何在?如果你是正确的,那么没有理由不使用抽象类,因为无论如何都不能实例化带有两个或更多接口的类。 - Vasja Filippov
已对弃用的转换进行了更正。您仍然可以实例化实现接口的对象。接口的目的类似于组件,您可以声明在多个不相关的类中使用的函数。这样做的一个有用案例是,您可以声明一个期望指向该接口的指针的函数。函数本身并不关心它是什么类型的对象,它只关心它实现了从该接口声明的函数。 - DW_Ant
那么你的意思是没有办法通过属性获取接口实现类型并将其实例化为TScriptInterface属性吗? - Vasja Filippov
很抱歉,我不完全理解您所说的获取实现类型接口的意思。我猜想您想要获取一个接口类的句柄,就像UClasses一样,然后使用它的引用来实例化该特定类型的对象。例如:GetWorld()->SpawnActor(UCoordinateSystem::StaticClass())。与子类相关联的接口在编译时进行评估,不能在运行时修改。这就像试图在运行时更改对象的超类一样。如果是这种情况,我认为组件是您要寻找的东西。 - DW_Ant
不,我不是。例如:我有一些接口 IMyInterface 和一些类似 UMyClass : UObject, IMyInterface 的类。我想通过属性像 TSubclassOf<SomeType> 或者 UClass 获取任何一个类的类型,并实例化它。然后我想将它存储在某个变量中以供以后使用。在最后的评论中,我问是否只能使用抽象类而不是接口才能实现这一点。 - Vasja Filippov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接