目錄
- 直接屬性引用
- 共享指針 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
正春華枝俏,待秋實果茂,愿與君共勉