【UE5 C++課程系列筆記】21——弱指針的簡單使用

目錄

概念

聲明和初始化

轉換為共享指針

打破循環引用

弱指針使用警告


概念

????????在UE C++ 中,弱指針(TWeakPtr?)也是一種智能指針類型,主要用于解決循環引用問題以及在不需要強引用保證對象始終有效的場景下,提供一種可以獲取對象訪問權限的方式。與共享指針(TSharedPtr?)和共享引用(TSharedRef?)不同,弱指針不會增加其所指向對象的引用計數,這意味著它不會對對象的生命周期產生維持作用,即不會阻止對象被銷毀。

????????例如,在一些復雜的對象關系結構中,多個對象之間可能相互引用,如果都使用強引用(如?TSharedPtr?或?TSharedRef?),很容易形成循環引用,導致對象的引用計數永遠無法降為 0,從而造成內存泄漏。而弱指針可以在這種情況下參與對象的引用關系構建,避免出現循環引用問題,同時又能在對象仍然存在時,有機會獲取到對象的有效訪問權限。

????????在訪問弱指針引用的對象前,應使用?Pin?函數生成共享指針。此操作確保使用該對象時其將繼續存在。如只需要確定弱指針是否引用對象,可將其與?nullptr?比較,或在之上調用?IsValid

聲明和初始化

? ? ? ? 在如下代碼中,體現了弱指針不維持對象生命周期的特點,以及通過?Pin?函數檢查對象是否還能獲取有效訪問權限的用法。

????????在第16行代碼中,使用?MakeShared<FMyStruct>()?創建了一個?FMyStruct?類型的對象,并通過?TSharedRef?來管理這個對象,使得?ObjectOwnerRef?指向新創建的對象。此時,該對象的引用計數被初始化為?1。

????????第17行代碼通過將?ObjectOwnerRef?作為參數傳遞給?TWeakPtr?的構造函數,創建了一個弱指針?ObjectObserver,使其指向與?ObjectOwnerRef?相同的?FMyStruct?對象。需要注意的是,這個操作并不會增加對象的引用計數,對象的生命周期仍然僅由?ObjectOwnerRef?(以及后續可能出現的其他指向該對象的共享指針或共享引用)來維持,ObjectObserver?只是建立了一個對該對象的弱引用關系,用于后續在不影響對象生命周期的情況下嘗試獲取對對象的訪問權限。

????????第18行代碼創建了一個?TSharedPtr?類型的共享指針?ObjectOwnerPtr,并通過賦值操作讓它也指向?ObjectOwnerRef?所指向的?FMyStruct?對象。此時,對象的引用計數會從?1(僅由?ObjectOwnerRef?維持時)變為?2。

????????第19行代碼調用?ObjectOwnerPtr?的?Reset?函數,這會使得?ObjectOwnerPtr?釋放對其所指向對象的強引用,對象的引用計數會相應地減?1。在執行完這行代碼后,對象的引用計數變回?1,僅由?ObjectOwnerRef?來維持其生命周期。

????????第20~23行代碼使用了?弱指針ObjectObserver?的?Pin?函數來嘗試獲取一個指向原對象的臨時共享指針,以檢查對象是否仍然可以被訪問。Pin?函數會在對象仍然存在(即對應的引用計數大于?0?)的情況下,返回一個指向該對象的臨時?TSharedPtr

轉換為共享指針

??Pin?函數將創建指向弱指針對象的共享指針。只要共享指針在范圍內且引用對象,則該對象將持續有效。

????????如下代碼主要展示了如何將一個由共享引用(TSharedRef?)管理的對象轉換為可通過弱指針(TWeakPtr?)來間接訪問的形式,并且演示了通過弱指針的?Pin?操作獲取臨時共享指針(TSharedPtr?),進而訪問對象成員函數?PrintAA?的過程,整體體現了弱指針在不影響對象生命周期管理的情況下,實現對對象的安全訪問機制。

打破循環引用

出現循環引用的示例:

首先在“FMyStruct”結構體中定義一個共享指針?HoldPtr,并初始化為?nullptr

然后創建兩個?FMyStruct?類型的對象,并通過它們各自包含的?TSharedPtr<FMyStruct>?類型成員變量?HoldPtr?互相指向對方,形成了一個循環引用的結構,如下所示。

此時調用“LoopPtr”會發現,并沒有輸出析構的日志信息,說明產生了循環引用現象,導致對象的引用計數永遠無法降為 0。

為了打破循環引用,我們可以使用弱指針來代替共享指針

編譯后運行 結果如下,可以看到對象可以正常析構了:

弱指針使用警告

????????如不想保證數據對象會持續存在時,弱指針將非常有用,但該屬性可能會變得異常危險。在以下情況中請謹慎使用弱指針:

  • **在Set或Map中用作鍵。弱指針可能會在未通知容器的情況下隨時無效,因此共享指針或共享引用更適用于充當鍵。可安全地將弱指針用作數值。

  • 雖然弱指針提供?IsValid?函數,但是檢查?IsValid?無法保證對象在任何時間長度內均可持續有效。線程安全共享指針可能會因另一線程上的活動而隨時無效,因此使用線程安全共享指針應尤其注意。Pin?返回的共享指針將使對象在代碼將其清除或其超出范圍前保持活躍狀態,因此?Pin?函數是用于檢查的首選方法,此類檢查會導致取消引用或訪問存儲對象。

官方文檔地址:

https://dev.epicgames.com/documentation/zh-cn/unreal-engine/shared-references-in-unreal-engine?application_version=5.3

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64946.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64946.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64946.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據庫知識匯總2

一. 范式 定義&#xff1a;范式是符合某一種級別的關系模式的集合。 關系數據庫中的關系必須滿足一定的要求。滿足不同程度要求的為不同范式&#xff1b; 一個低一級范式的關系模式&#xff0c;通過模式分解&#xff08;schema decomposition&#xff09;可以轉換為若干個高一…

C# 設計模式(結構型模式):橋接模式

C# 設計模式&#xff08;結構型模式&#xff09;&#xff1a;橋接模式 在軟件設計中&#xff0c;我們經常會遇到系統的變化頻繁&#xff0c;或者需要靈活擴展功能的場景。這時&#xff0c;橋接模式&#xff08;Bridge Pattern&#xff09;便顯得尤為重要。橋接模式是一個結構型…

Flash Attention V3使用

Flash Attention V3 概述 Flash Attention 是一種針對 Transformer 模型中注意力機制的優化實現&#xff0c;旨在提高計算效率和內存利用率。隨著大模型的普及&#xff0c;Flash Attention V3 在 H100 GPU 上實現了顯著的性能提升&#xff0c;相比于前一版本&#xff0c;V3 通…

【51單片機零基礎-chapter6:LCD1602調試工具】

實驗0-用顯示屏LCD驗證自己的猜想 如同c的cout,前端的console.log() #include <REGX52.H> #include <INTRINS.H> #include "LCD1602.h" int var0; void main() {LCD_Init();LCD_ShowNum(1,1,var211,5);while(1){;} }實驗1-編寫LCD1602液晶顯示屏驅動函…

【網絡】ARP表、MAC表、路由表

ARP表 網絡設備存儲IP-MAC映射關系的表項&#xff0c;便于快速查找和轉發數據包 ARP協議工作原理 ARP&#xff08;Address Resolution Protocol&#xff09;&#xff0c;地址解析協議&#xff0c;能夠將網絡層的IP地址解析為數據鏈路層的MAC地址。 1.主機在自己的ARP緩沖區中建…

Ubuntu22.04雙系統安裝記錄

1.Ubuntu24.04在手動分區時&#xff0c;沒有efi選項&#xff0c;需要點擊分區界面左下角&#xff0c;選擇efi的位置&#xff0c;然后會自動創建/boot/efi分區&#xff0c;改到2GB大小即可。 2.更新Nvidia驅動后&#xff0c;重啟電腦wifi消失&#xff0c;參考二選一&#xff1a…

Python Notes 1 - introduction with the OpenAI API Development

Official document&#xff1a;https://platform.openai.com/docs/api-reference/chat/create 1. Use APIfox to call APIs 2.Use PyCharm to call APIs 2.1-1 WIN OS.Configure the Enviorment variable #HK代理環境&#xff0c;不需要科學上網(價格便宜、有安全風險&#…

【Python其他生成隨機字符串的方法】

在Python中&#xff0c;除了之前提到的方法外&#xff0c;確實還存在其他幾種生成隨機字符串的途徑。以下是對這些方法的詳細歸納&#xff1a; 方法一&#xff1a;使用random.randint結合ASCII碼生成 你可以利用random.randint函數生成指定范圍內的隨機整數&#xff0c;這些整…

leetcode hot 100 跳躍游戲

55. 跳躍游戲 已解答 中等 相關標簽 相關企業 給你一個非負整數數組 nums &#xff0c;你最初位于數組的 第一個下標 。數組中的每個元素代表你在該位置可以跳躍的最大長度。 判斷你是否能夠到達最后一個下標&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否則…

《Vue3實戰教程》40:Vue3安全

如果您有疑問&#xff0c;請觀看視頻教程《Vue3實戰教程》 安全? 報告漏洞? 當一個漏洞被上報時&#xff0c;它會立刻成為我們最關心的問題&#xff0c;會有全職的貢獻者暫時擱置其他所有任務來解決這個問題。如需報告漏洞&#xff0c;請發送電子郵件至 securityvuejs.org。…

01.02周二F34-Day44打卡

文章目錄 1. 這家醫院的大夫和護士對病人都很耐心。2. 她正跟一位戴金邊眼鏡的男士說話。3. 那個人是個圓臉。4. 那個就是傳說中的鬼屋。5. 他是個很好共事的人。6. 我需要一杯提神的咖啡。7. 把那個卷尺遞給我一下。 ( “卷尺” 很復雜嗎?)8. 他收到了她將乘飛機來的消息。9.…

Spring Boot項目中使用單一動態SQL方法可能帶來的問題

1. 查詢計劃緩存的影響 深入分析 數據庫系統通常會對常量SQL語句進行編譯并緩存其執行計劃以提高性能。對于動態生成的SQL語句&#xff0c;由于每次構建的SQL字符串可能不同&#xff0c;這會導致查詢計劃無法被有效利用&#xff0c;從而需要重新解析、優化和編譯&#xff0c;…

【Rust自學】10.2. 泛型

喜歡的話別忘了點贊、收藏加關注哦&#xff0c;對接下來的教程有興趣的可以關注專欄。謝謝喵&#xff01;(&#xff65;ω&#xff65;) 題外話&#xff1a;泛型的概念非常非常非常重要&#xff01;&#xff01;&#xff01;整個第10章全都是Rust的重難點&#xff01;&#xf…

Spark-Streaming有狀態計算

一、上下文 《Spark-Streaming初識》中的NetworkWordCount示例只能統計每個微批下的單詞的數量&#xff0c;那么如何才能統計從開始加載數據到當下的所有數量呢&#xff1f;下面我們就來通過官方例子學習下Spark-Streaming有狀態計算。 二、官方例子 所屬包&#xff1a;org.…

Python 3 輸入與輸出指南

文章目錄 1. 輸入與 input()示例&#xff1a;提示&#xff1a; 2. 輸出與 print()基本用法&#xff1a;格式化輸出&#xff1a;使用 f-string&#xff08;推薦&#xff09;&#xff1a;使用 str.format()&#xff1a;使用占位符&#xff1a; print() 的關鍵參數&#xff1a; 3.…

【SQLi_Labs】Basic Challenges

什么是人生&#xff1f;人生就是永不休止的奮斗&#xff01; Less-1 嘗試添加’注入&#xff0c;發現報錯 這里我們就可以直接發現報錯的地方&#xff0c;直接將后面注釋&#xff0c;然后使用 1’ order by 3%23 //得到列數為3 //這里用-1是為了查詢一個不存在的id,好讓第一…

Swift Combine 學習(四):操作符 Operator

Swift Combine 學習&#xff08;一&#xff09;&#xff1a;Combine 初印象Swift Combine 學習&#xff08;二&#xff09;&#xff1a;發布者 PublisherSwift Combine 學習&#xff08;三&#xff09;&#xff1a;Subscription和 SubscriberSwift Combine 學習&#xff08;四&…

時間序列預測算法---LSTM

目錄 一、前言1.1、深度學習時間序列一般是幾維數據&#xff1f;每個維度的名字是什么&#xff1f;通常代表什么含義&#xff1f;1.2、為什么機器學習/深度學習算法無法處理時間序列數據?1.3、RNN(循環神經網絡)處理時間序列數據的思路&#xff1f;1.4、RNN存在哪些問題? 二、…

leetcode題目(3)

目錄 1.加一 2.二進制求和 3.x的平方根 4.爬樓梯 5.顏色分類 6.二叉樹的中序遍歷 1.加一 https://leetcode.cn/problems/plus-one/ class Solution { public:vector<int> plusOne(vector<int>& digits) {int n digits.size();for(int i n -1;i>0;-…

快速上手LangChain(三)構建檢索增強生成(RAG)應用

文章目錄 快速上手LangChain(三)構建檢索增強生成(RAG)應用概述索引阿里嵌入模型 Embedding檢索和生成RAG應用(demo:根據我的博客主頁,分析一下我的技術棧)快速上手LangChain(三)構建檢索增強生成(RAG)應用 langchain官方文檔:https://python.langchain.ac.cn/do…