TObjectPtr、TSharedPtr、TWeakPtr、TSoftObjectPtr 的区别与使用场景
在使用 Unreal Engine 5(UE5) 进行开发时,可能会遇到不同种类的智能指针类型:TObjectPtr
、TSharedPtr
、TWeakPtr
、TSoftObjectPtr
等。它们虽然都具有管理对象生命周期或访问对象的作用,但底层机制与应用场景大不相同。
一、TObjectPtr —— 原生 UObject 指针封装(UE5引入)
概念
TObjectPtr<T>
是 UE5 中引入的新指针类型,用来替代原生的 T*
指针用于引用 UObject
子类实例的情况,目的是加强 GC系统的追踪能力 和 内存安全性。
特点
- 只能用于继承自
UObject
的类型; - 自动参与 GC(垃圾回收);
- 避免野指针,增强 GC 识别;
- 开销极小,运行时几乎等价于原始指针。
使用场景
- 类成员变量中引用
UObject
实例时; - 替代裸
UObject*
指针,用于被 GC 管理的对象; - 需要序列化支持或编辑器暴露时。
示例
1 | UPROPERTY() |
二、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 | TWeakPtr<FMyStruct> WeakData = SharedData; |
四、TSoftObjectPtr —— 延迟加载资源的弱引用(支持 UObject)
概念
TSoftObjectPtr<T>
是 Unreal 中的软引用指针,保存的是资源路径,不直接加载对象。只有在需要时才加载资源,常用于延迟加载、解耦引用关系等。
特点
- 支持
UObject
及其子类 - 不参与 GC
- 可序列化为资源路径
- 支持同步或异步加载
使用场景
- 引用大型资源(如贴图、蓝图、关卡等)
- 减少依赖、解耦资源引用
- 延迟加载优化性能
示例
UPROPERTY(EditAnywhere)
TSoftObjectPtr<UTexture2D> SoftTexture;
UTexture2D* LoadedTexture = SoftTexture.LoadSynchronous(); // 同步加载