目录
- 直接属性引用
- 共享指针 TSharedPtr
- 实现原理
- 共享引用 TSharedRef
- 弱引用指针 TWeakPtr
- Object弱指针 FWeakPtr
- 实现原理
- Object软指针 FSoftObjectPtr
- 原理
直接属性引用
在c++通过UPROPERTY()宏将属性公开,蓝图中属性类型中的Object Reference。
- 对一个类型及其子类型的引用:
- 在c++中: TSubclassOf< TypeName >,指定派生自TypeName的子类型。
- 在蓝图中:即属性类型中的Class Reference。
# 裸指针
类型* 指针名
,只保存对象地址
悬挂指针问题
当指针指向的内存被释放时,指针仍保持该地址(不为nullptr),此时程序访问指针就会导致错误,导致悬挂指针问题。此时可以使用共享指针TSharedPtr以解决问题。
共享指针 TSharedPtr
TSharedPtr通过引用计数解决悬挂指针问题。
实现原理
- TSharedPtr中保存着指向对象的裸指针和引用计数器 FReferenceControllerBase* ReferenceController。
- TSharedPtr运用了RAII即资源获取即初始化的思想(Resource Acquisition Is Initialization),在指针的构造函数中增加ReferenceController中的共享引用计数,在析构函数中减少计数,当计数为0时,计数器ReferenceController释放指向的对象并释放所有弱引用WeakReference。
循环引用问题
当两个共享指针相互指向时,两者的计数都最少是1,并且两个指针指向的对象都不会被释放。此时需要和弱指针TWeakPtr一起使用以解决问题
—
共享引用 TSharedRef
TSharedRef和TSharedPtr的关系就像引用与指针的关系,TSharedRef几乎所有操作都和TSharedPtr相同。
TSharedRef必须在声明时初始化,但不能像引用那样使用“ . ”操作符,TSharedRef必须使用“ -> ”操作符。
TSharedPtr可以使用ToSharedRef() 方法转换为TSharedRef。
弱引用指针 TWeakPtr
- TWeakPtr解决了TSharedPtr的循环引用问题。
- TWeakPtr几乎和TSharedPtr相同,但TWeakPtr增加或减少的计数是弱引用计数WeakReferenceCount,和TSharedPtr的计数分开计算引用次数。
- 在TWeakPtr计数为0时,会删除计数器ReferenceController。
Object弱指针 FWeakPtr
FWeakObjectPtr是指向UObject对象的弱指针,其不会干涉UObject对象的GC(垃圾回收),而是在该UObject对象未被GC时返回该原对象,在*被GC后返回nullptr。
- 弱引用不会增加UObject对象的引用计数,不会阻止其GC,只监控其状态,在其被GC时自动失效置空。
实现原理
弱引用提供Get()函数来获取其指向的UObject对象,该函数中调用 Internal_Get()。Internal_Get()中调用 Internal_GetObjectItem() ,判断对象有效性、根据有效性返回对象或nullptr。
TBD
Object软指针 FSoftObjectPtr
FSoftObjectPtr是指向UObject对象的弱指针,通过间接机制引用对象(如记录对象在磁盘上的路径)。
其可以安全地检查资源是否已加载,当引用的对象加载或卸载时,它会在**有效(Valid)和挂起(Pending)**之间切换状态。
- 有效(Valid):这意味这其指向了一个真实的UObject对象,并且该UObject已经加载到了内存上。此时可以使用Get()函数获取此UObject。
- 挂起(Pending):这意味着指向的UObject尚未完全加载到内存中。可以使用 IsPending() 函数获取指向的UObject是否加载完毕。
- 软引用指针的状态会随着指向的对象的加载情况而动态切换
- 当其创建或重新指向一个UObjcet时,状态可能会是挂起,因为UObject可能需要进行异步加载。
- 当加载完成后,状态会从挂起切换为有效,表示指向的UObject已经可以正常访问。
- 如果指向的UObject被卸载或销毁,弱引用指针的状态会切换回挂起,表示UObject已经不再有效。
原理
TBD
正春华枝俏,待秋实果茂,愿与君共勉