TObjectPtr、TSharedPtr、TWeakPtr、TSoftObjectPtr 的区别与使用场景

在使用 Unreal Engine 5(UE5) 进行开发时,可能会遇到不同种类的智能指针类型:TObjectPtrTSharedPtrTWeakPtrTSoftObjectPtr 等。它们虽然都具有管理对象生命周期或访问对象的作用,但底层机制与应用场景大不相同。


一、TObjectPtr —— 原生 UObject 指针封装(UE5引入)

概念

TObjectPtr<T> 是 UE5 中引入的新指针类型,用来替代原生的 T* 指针用于引用 UObject 子类实例的情况,目的是加强 GC系统的追踪能力内存安全性

特点

  • 只能用于继承自 UObject 的类型;
  • 自动参与 GC(垃圾回收);
  • 避免野指针,增强 GC 识别;
  • 开销极小,运行时几乎等价于原始指针。

使用场景

  • 类成员变量中引用 UObject 实例时;
  • 替代裸 UObject* 指针,用于被 GC 管理的对象;
  • 需要序列化支持或编辑器暴露时。

示例

1
2
UPROPERTY()
TObjectPtr<UMyDataAsset> DataAsset;

二、TSharedPtr —— 引用计数智能指针(非 UObject)

概念

TSharedPtr<T> 是 Unreal 的引用计数智能指针,功能类似于 std::shared_ptr,可自动管理对象生命周期。但 不能 用于 UObject 类型(与 GC 不兼容)。

特点

  • 基于引用计数,自动析构
  • 不支持 GC
  • 可用于自定义非 UObject 类型
  • 可线程安全(使用 ESPMode::ThreadSafe

使用场景

  • 管理普通 C++ 对象
  • 多处共享使用同一对象
  • 工具类、数据模型、非资源对象等

示例

1
TSharedPtr<FMyStruct> SharedData = MakeShared<FMyStruct>();

三、TWeakPtr —— 非拥有式弱引用(非 UObject)

概念

TWeakPtr<T> 是与 TSharedPtr 搭配使用的非拥有引用,不增加引用计数,可避免循环引用,常用于缓存、观察者模式等。

特点

  • 不拥有对象
  • 不参与引用计数
  • 访问前需通过 .Pin() 检查有效性
  • 适用于非 UObject 类型

使用场景

  • 缓存对象
  • 观察者模式监听者
  • 避免共享引用造成内存泄露

示例

1
2
3
4
5
TWeakPtr<FMyStruct> WeakData = SharedData;
if (TSharedPtr<FMyStruct> Pinned = WeakData.Pin())
{
// 安全访问对象
}

四、TSoftObjectPtr —— 延迟加载资源的弱引用(支持 UObject)

概念

TSoftObjectPtr<T> 是 Unreal 中的软引用指针,保存的是资源路径,不直接加载对象。只有在需要时才加载资源,常用于延迟加载、解耦引用关系等。

特点

  • 支持 UObject 及其子类
  • 不参与 GC
  • 可序列化为资源路径
  • 支持同步或异步加载

使用场景

  • 引用大型资源(如贴图、蓝图、关卡等)
  • 减少依赖、解耦资源引用
  • 延迟加载优化性能

示例

UPROPERTY(EditAnywhere)
TSoftObjectPtr<UTexture2D> SoftTexture;

UTexture2D* LoadedTexture = SoftTexture.LoadSynchronous(); // 同步加载