指针嵌套指针 拷贝_C++智能指针小结
C++中的智能指針包括auto_ptr, unique_ptr, shared_ptr, weak_ptr. 其中 auto_ptr已被棄用.
unique_ptr
unique_ptr是大部分情況下的首選, 體現獨占的語義. 當unique_ptr被銷毀時, 其指向的原始指針也自動被銷毀.
unique_ptr體現資源的獨占, 因此無法被拷貝, 沒有拷貝構造和拷貝賦值函數. 但是unique_ptr的所有權是可以通過move操作轉移的, 由移動構造和移動賦值函數實現.
unique_ptr默認通過delete實現對象銷毀. 你也可以在構造時指定unique_ptr的銷毀函數.
使用默認的銷毀函數時, unique_ptr的大小和原始指針相同. 使用自定義銷毀器時, unique_ptr會將銷毀器的類封裝在unique_ptr中, 因此應盡量使用無狀態的函數對象(沒有捕獲的lambda表達式或仿函數)作為銷毀器, 此時unique_ptr的大小仍然和原始指針相同.
// 64bits platformunique_ptr可以像原始指針那樣用基類指針指向子類對象, 當然為了能正確析構對象, 你需要將析構函數聲明為虛函數.
unique_ptr無法從原始指針隱式轉換而來.
unique_ptr也可以用于數組對象 unique_ptr<T[]>, unique_ptr重載了[]操作符.
unique_ptr可以被隱式轉換為shared_ptr, 因此一個工廠方法應盡量返回unique_ptr對象.
shared_ptr
shared_ptr體現共享的語義, shared_ptr從一個原始指針構造一個初始的對象, 并創建一個控制塊. 從初始對象可以復制多個shared_ptr, 復制的對象共享控制塊. 每個shared_ptr會使控制塊中引用計數+1, 當所有shared_ptr被銷毀時, 控制塊中計數變為0, 原始指針亦被銷毀.
從shared_ptr復制(拷貝構造和拷貝賦值)時會使引用計數+1, 移動時(移動構造和移動賦值)引用計數不變.
shared_ptr的大小是固定的2倍原始指針大小, 一個是指向原始指針, 一個指向控制塊.
shared_ptr的控制塊內存是動態分配的, 在首次創建初始shared_ptr對象時分配.
shared_ptr的引用計數增減必須是原子性的, 這會導致一些性能消耗.
和unique_ptr一樣, shared_ptr也可以自定義銷毀器. 但是不同的是, shared_ptr的銷毀器是放在控制塊內存中的, 不會影響shared_ptr的類型和本身的大小. 這也意味著你可以在同一容器中放置元素類型相同但銷毀器不同的shared_ptr.
首次創建初始對象時會創建控制塊內存. 因此, 需要避免從一個原始指針多次創建shared_ptr對象, 這樣會導致原始指針被析構兩次.
autoshared_ptr 同樣適用于數組(c++17后).
weak_ptr
weak_ptr是shared_ptr的一個增強功能, 通常從shared_ptr創建. 不同的是, weak_ptr不會影響指向對象的引用計數.
weak_ptr使用expired()函數檢查對象的引用計數是否為0, 即檢查對應的shared_ptr是否過期.你可能會嘗試這樣使用weak_ptr:
auto這樣檢查shared_ptr是否過期, 然后使用weak_ptr. 但是在多線程情況下這樣做可能有一些風險, 多線程下正確的方式是這樣使用weak_ptr:
std使用lock()返回一個shared_ptr, 然后使用返回的shared_ptr對象.
控制塊中同樣保存有weak_ptr的弱引用計數, 當控制塊中的引用計數和弱引用計數都為0時, 控制塊會被銷毀.
enable_shared_from_this
很多情況下, 我們需要在一個對象內部使用包含this指針的shared_ptr對象, 或者從某個函數返回包含this指針的shared_ptr. 這時我們需要繼承enable_shared_from_this, 然后用shared_from_this() 創建一個包含this指針的shared_ptr:
classenable_shared_from_this的原理是在enable_shared_from_this中存儲了一個weak_ptr<Widget>對象. 當Widget對象被創建時, 這個weak_ptr置為指向nullptr. 當從一個Widget指針創建shared_ptr時, 會檢測Widget對象是否繼承了enable_shared_from_this. 如果繼承了, 會將其內部的weak_ptr指向剛剛創建的shared_ptr.
這樣, 這個weak_ptr就關聯了一個包含this指針的shared_ptr, shared_from_this()其實就是從weak_ptr再次創建shared_ptr. 如果shared_from_this()前不曾用this創建過shared_ptr, weak_ptr就是指向nullptr的, 這時會拋出bad_weak_ptr異常.
make_shared
一般情況下, 更推薦使用make_shared來構造shared_ptr.
make_shared相對于直接從原始指針創建shared_ptr的優點有:
缺點有:
總結
以上是生活随笔為你收集整理的指针嵌套指针 拷贝_C++智能指针小结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python语言具有使用变量需要先定义后
- 下一篇: stm32f105vct6例程_STM3