日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

智能指针详解

發布時間:2024/3/26 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 智能指针详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原理

智能指針是一個類,用來存儲指向動態分配對象的指針,負責自動釋放動態分配的對象,防止堆內存泄漏。動態分配的資源,交給一個類對象去管理,當類對象聲明周期結束時,自動調用析構函數釋放資源

導引:

? ? ?智能指針最初只有auto_ptr,c++98版本的。但是auto_ptr存在一個致命問題是,它支持拷貝語義嘛。所以就會造成對一個指針delete兩次的問題,不安全。

? ? ?而解決對一個指針多次delete的問題,一共有三種解決思路

  • ?加一個所有權,只有一個指針具有該內存的所有權,其他指針就算拷貝了,也不能進行析構?——》unique_ptr應運而生
  • 加一個引用計數,?一個指針引用,count就++,拷貝也會count++,賦值的話,左值的count--,右值的count++——》shared_ptr應運而生
  • 定義賦值運算符,使之執行深復制。這樣兩個指針將指向不同的對象,其中的一個對象是另一個對象的副本,缺點是浪費空間,所以智能指針都未采用此方案
  • 同時因為shared_ptr具有循環引用的問題,所以加一個智能指針weak_ptr作為shared_ptr的輔助指針來解決循環引用的問題。
  • 常用的智能指針

    (1) shared_ptr

    實現原理:采用引用計數器的方法,允許多個智能指針指向同一個對象,每當多一個指針指向該對象時,指向該對象的所有智能指針內部的引用計數加1,每當減少一個智能指針指向對象時,引用計數會減1,當計數為0的時候會自動的釋放動態分配的資源。

  • ? ? ?? 1、智能指針將一個計數器與類指向的對象相關聯,引用計數器跟蹤共有多少個類對象共享同一指針每次創建類的新對象時,初始化指針并將引用計數置為1。
  • ? ? ? ?2、當對象作為另一對象的副本而創建時,拷貝構造函數拷貝指針并增加與之相應的引用計數
  • ? ? ? ?3、對一個對象進行賦值時,賦值操作符減少左操作數所指對象的引用計數(如果引用計數為減至0,則刪除對象),并增加右操作數所指對象的引用計數
  • ? ? ? ?4、調用析構函數時,減少引用計數(如果引用計數減至0,則刪除基礎對象)
  • (2) unique_ptr

    ? ? ? ?unique_ptr采用的是獨享所有權語義,一個非空的unique_ptr總是擁有它所指向的資源。轉移一個unique_ptr將會把所有權全部從源指針轉移給目標指針,源指針被置空;所以unique_ptr不支持普通的拷貝和賦值操作,不能用在STL標準容器中;局部變量的返回值除外(因為編譯器知道要返回的對象將要被銷毀);如果你拷貝一個unique_ptr,那么拷貝結束后,這兩個unique_ptr都會指向相同的資源,造成在結束時對同一內存指針多次釋放而導致程序崩潰。

    ? ? ? ?在智能指針生命周期內,可以改變智能指針所指對象,如創建智能指針時通過構造函數指定、通過 reset 方法重新指定、通過 release 方法釋放所有權、通過移動語義轉移所有權,unique_ptr 還可能沒有對象,這種情況被稱為 empty。

    ? ? ? ?unique_ptr 可放在容器中,彌補了 auto_ptr 不能作為容器元素的缺點。只要對容器元素不使用拷貝操作的算法即可(如 sort())

    ? ? ? ?unique_ptr 比 auto_ptr 更加安全,因為 auto_ptr 有拷貝語義,拷貝后原對象變得無效,再次訪問原對象時會導致程序崩潰;unique_ptr 則禁止了拷貝語義,但提供了移動語義,即可以使用 std::move() 進行控制權限的轉移

    (3) weak_ptr

    ? ? ? ?weak_ptr:弱引用。 引用計數有一個問題就是互相引用形成環(環形引用),這樣兩個指針指向的內存都無法釋放。需要使用weak_ptr打破環形引用。weak_ptr是一個弱引用,它是為了配合shared_ptr而引入的一種智能指針,它指向一個由shared_ptr管理的對象而不影響所指對象的生命周期,也就是說,它只引用,不計數。如果一塊內存被shared_ptr和weak_ptr同時引用,當所有shared_ptr析構了之后,不管還有沒有weak_ptr引用該內存,內存也會被釋放。所以weak_ptr不保證它指向的內存一定是有效的,在使用之前使用函數lock()檢查weak_ptr是否為空指針

    lock函數?檢查 weak_ptr 所指的對象是否仍存在,如果存在,返回一個指向共享對象的 shared_ptr,不存在則返回

    w.lock(); //如果expired()為true,返回一個空shared_ptr,否則返回非空shared_ptr。

    (4) auto_ptr

    auto_ptr 是標準庫的較早版本包含的一個類,它具有 unique_ptr 的部分特性。相比于unique_ptr,不能在容器中保存 auto_ptr,也不能從函數返回 auto_ptr。盡量使用unique_ptr

    主要是為了解決“有異常拋出時發生內存泄漏”的問題 。因為發生異常而無法正常釋放內存。

    auto_ptr有拷貝語義,拷貝后源對象變得無效,這可能引發很嚴重的問題;而unique_ptr則無拷貝語義,但提供了移動語義,這樣的錯誤不再可能發生,因為很明顯必須使用std::move()進行轉移。

    auto_ptr不支持拷貝和賦值操作,不能用在STL標準容器中。STL容器中的元素經常要支持拷貝、賦值操作,在這過程中auto_ptr會傳遞所有權,所以不能在STL中使用。

    總結

    以上是生活随笔為你收集整理的智能指针详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。