SuperAPI AI 工具集

cpp-fundamentals

编程与开发

查看项目

更新于 11-06 16:21

技能介绍

本技能聚焦虚幻引擎 C++ 编程中由 Unreal Header Tool(UHT)生成的反射层,帮助开发者写出能正确编译、在蓝图中可见、可网络复制并经得起垃圾回收的代码。

用途

适用于在 C++ 中创建或编辑任意 U* 类、A* 类或 F* 结构体;将成员或函数暴露给蓝图、编辑器或网络复制;诊断 UHT 报错(如“Unrecognized type”“missing generated.h”“GENERATED_BODY missing”);在 TObjectPtr、裸指针、TWeakObjectPtr 与 TSharedPtr 之间做选择;理解 CDO 机制及构造函数为何在编辑器中也运行。

核心心智模型

  • UObject 是反射与 GC 对象图的基类,所有加入该系统的类都直接或间接派生自它。
  • UHT 在编译器之前解析头文件,生成 <ClassName>.generated.h,包含反射、序列化与蓝图集成的样板代码;该文件必须最后包含,并在类型内放置 GENERATED_BODY()。
  • UClass 是运行时类型描述符,持有类默认对象(CDO);新实例从 CDO 复制,构造函数会在 CDO 和编辑器中运行,因此不能放游戏逻辑。
  • UObject 受 GC 管理,需要保活的 UObject* 必须存于 UPROPERTY,普通 C++ 指针对 GC 不可见,可能悬空。

类前缀

U(UObject 派生非 Actor)、A(Actor 派生)、F(普通结构体/值类型)、E(枚举)、I(接口)、T(模板)、S(Slate 控件)。前缀后的类名须与文件名一致,如 AMyPawn 位于 MyPawn.h/MyPawn.cpp。

类结构要点

头文件中 #include "X.generated.h" 必须是最后一个 include;每个反射类/结构体都要有 GENERATED_BODY();类需标注模块 API 宏(如 MYGAME_API);重写引擎虚函数(BeginPlay、Tick、EndPlay 等)时始终调用 Super::。

常用说明符

  • UCLASS:Blueprintable、BlueprintType、Abstract、Config=Game、MinimalAPI、meta 排序提示等。
  • UPROPERTY:EditAnywhere/EditDefaultsOnly/EditInstanceOnly 及 Visible 系列控制可见性;BlueprintReadWrite/BlueprintReadOnly 控制蓝图访问;Category 分组;meta ClampMin/ClampMax、AllowPrivateAccess;Transient、SaveGame、Replicated/ReplicatedUsing、Instanced 等。
  • UFUNCTION:BlueprintCallable、BlueprintPure、BlueprintImplementableEvent、BlueprintNativeEvent(配合 Func_Implementation)、CallInEditor、Exec、Server/Client/NetMulticast 及可靠/不可靠 RPC。

USTRUCT、UENUM、UINTERFACE

USTRUCT 是值类型,无 GC、无 CDO、不能用 NewObject;适合轻量数据包。UENUM 用于蓝图时须以 uint8 为底层类型。UINTERFACE 须成对声明 U* 外壳与 I* C++ 接口。

对象创建与指针选择

  • CreateDefaultSubobject 仅限构造函数,名称在类内唯一。
  • NewObject 用于运行时非 Actor 对象;Actor 用 SpawnActor。
  • 转换用 Cast<T>,有效性用 IsValid。
  • 需要保活的 UObject 成员用 UPROPERTY() TObjectPtr<UType>;局部变量或参数可用裸指针;非拥有引用用 TWeakObjectPtr 并先检查 IsValid;非 UObject 共享堆对象用 TSharedPtr/TSharedRef;按需加载资源用 TSoftObjectPtr/TSoftClassPtr。

常见陷阱

忘记 UPROPERTY 导致 GC 后随机崩溃;generated.h 未放最后或缺少 GENERATED_BODY 引发难懂报错;在构造函数写游戏逻辑;在构造函数外调用 CreateDefaultSubobject 触发断言;从运行时代码调用编辑器专用 API 导致打包失败;UENUM 未用 uint8 导致蓝图不可用。

版本提示

TObjectPtr 为 UE5 引入;MarkPendingKill 在 UE5 改为 MarkAsGarbage,新默认下 GC 不再自动置空指针;直接访问 ClassDefaultObject 字段自 5.6 起弃用,改用 GetDefaultObject()。