1 UPROPERTY 使用
在Unreal Engine 4中,所有UObject实例都被垃圾回收系统管理。这意味着,如果没有任何强引用指向UObject实例,那么这个实例可能在任何时候被垃圾回收系统销毁。
强引用包括:在另一个UObject实例中的UPROPERTY指向它,或者在代码中有一个持有该实例的TArray、TMap、TSet、或UObject指针等其他强引用容器。
在你的情况下,你的管理类有一个TMap用来存储UObject实例。然而,这个TMap并不是UPROPERTY,所以它不被视为强引用。这就可能导致垃圾回收系统在任何时候销毁存储在TMap中的UObject实例,从而使TMap中的指针过时。
为了解决这个问题,你应该将你的TMap声明为UPROPERTY,这样垃圾回收系统就会知道这些UObject实例正在被使用,因此不会销毁它们:
```cpp
UCLASS()
class BOSI_API UXMLSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
UPROPERTY()
TMap<FString, UXMLConfig*> MapForConfigData;
// 你的其他代码
};
```
这样,只要你的管理类实例存在,垃圾回收系统就不会销毁存储在MapForConfigData中的UObject实例。
# 模板条件编译
2. `if constexpr`是C++17引入的一种条件编译指令。它允许在编译时根据常量表达式的值决定是否编译某段代码。在你的代码中,`TIsDerivedFrom<T, UMyConfigDataBase>::IsDerived`是一个编译时常量表达式,它会检查`T`是否是`UMyConfigDataBase`的派生类。如果`T`是`UMyConfigDataBase`的派生类,那么这个表达式的值为`true`,编译器将会编译`if constexpr`内部的代码。如果`T`不是`UMyConfigDataBase`的派生类,那么这个表达式的值为`false`,编译器将不会编译`if constexpr`内部的代码。这就允许你在模板函数中添加特定于某些类型的代码,而不会影响其他类型。
# 3 UFUNCTION
这个错误信息是在尝试绑定一个名为'Button1Click'的委托(Delegate)时发生的,特别是在初始化你的UHOME_UI用户界面时。错误信息的主要部分是:
```
LogOutputDevice: Error: Unable to bind delegate to 'Button1Click' (function might not be marked as a UFUNCTION or object may be pending kill)
```
这表明在试图将函数'Button1Click'绑定到一个委托时出现了问题。错误信息中给出了两种可能的原因:
1. 'Button1Click'可能没有被标记为UFUNCTION。在Unreal Engine 4中,任何需要被蓝图调用,或者需要作为事件处理器(如点击事件)的函数,都需要使用UFUNCTION宏进行标记。如果你没有这么做,UE4的反射系统将无法识别这个函数,从而无法将其绑定到委托。
2. 被引用的对象可能正在等待销毁(Pending Kill)。如果一个对象正在等待销毁,那么你将无法将其上的函数绑定到委托。这通常发生在一个对象被标记为销毁,但实际的销毁操作还没有发生时。
为了解决这个问题,你可以检查'Button1Click'函数是否被正确标记为UFUNCTION,并确保试图绑定的对象没有被标记为销毁。你也可以检查你的UHOME_UI类的Initialize函数,以及任何与'Button1Click'相关的代码,看看是否存在其他可能的问题。
# 4 UEC++中使用嵌套类
在C++中,嵌套结构体(或类)声明在某些情况下是允许的。然而,Unreal Engine 4的UCLASS宏不支持嵌套类或结构体声明。如果你尝试在UCLASS内部声明USTRUCT,你将会得到编译错误。
你可以将结构体声明放在同一个头文件中,但是需要在类的外部。例如:
```cpp
USTRUCT(BlueprintType)
struct FPlayerConfigDataStruct
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerConfigData")
FString Name;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerConfigData")
int32 Id;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerConfigData")
int32 Hp;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerConfigData")
int32 Mp;
};
UCLASS()
class UMyPlayerConfigData : public UMyConfigDataBase
{
GENERATED_BODY()
public:
//实现纯虚函数
virtual bool LoadDataWithXml(const FXmlNode* Node) override;
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="PlayerConfigData")
FPlayerConfigDataStruct PlayerData;
};
```
这样,你的结构体和类在同一个头文件中,但是结构体并没有在类内部声明。