c++++的智能指針有shared_ptr、unique_ptr和weak_ptr三種,各有特點。1.shared_ptr共享所有權,可復制,適用于多個對象共享資源,使用make_shared創建更高效,但需避免循環引用;2.unique_ptr獨占所有權,不可復制只能移動,效率高,適合單一所有者場景;3.weak_ptr用于觀察shared_ptr管理的對象,打破循環引用,需調用lock()獲取shared_ptr。選擇順序為優先unique_ptr,需要共享時選shared_ptr,輔助場景用weak_ptr。
c++的智能指針是現代C++中管理動態內存的重要工具,主要目的是避免內存泄漏和資源管理問題。目前常用的有三種:shared_ptr、unique_ptr和weak_ptr。它們各有特點,適用于不同的場景。
shared_ptr:共享所有權的智能指針
shared_ptr 是引用計數型智能指針,多個 shared_ptr 可以指向同一個對象,當最后一個指向該對象的指針被銷毀時,對象才會被釋放。
適用場景:
立即學習“C++免費學習筆記(深入)”;
- 多個對象需要共享一個資源的所有權
- 你不確定誰最后使用,也不希望提前釋放資源
建議:
- 盡量避免循環引用(A持有B的shared_ptr,B也持有A的),這會導致內存泄漏
- 使用 make_shared 創建對象,效率更高,也更安全
舉個例子:
auto ptr1 = std::make_shared<int>(10); auto ptr2 = ptr1; // 引用計數增加到2
注意點:
unique_ptr:獨占所有權的智能指針
unique_ptr 表示對資源的唯一擁有權,不能復制,只能移動(move)。它是最輕量級、最高效的智能指針之一。
適用場景:
立即學習“C++免費學習筆記(深入)”;
- 資源只屬于一個所有者
- 不允許復制,但可以在函數之間傳遞所有權
建議:
- 在不需要共享的時候優先使用 unique_ptr
- 返回或傳遞 unique_ptr 時使用 std::move
比如:
std::unique_ptr<int> ptr1(new int(20)); // std::unique_ptr<int> ptr2 = ptr1; // 編譯錯誤!不能復制 std::unique_ptr<int> ptr2 = std::move(ptr1); // OK,轉移所有權
優勢:
- 沒有運行時開銷
- 更清晰地表達資源歸屬關系
weak_ptr:觀察 shared_ptr 的助手
weak_ptr 并不擁有資源,它只是“觀察”某個由 shared_ptr 管理的對象。它可以用來解決 shared_ptr 的循環引用問題。
適用場景:
立即學習“C++免費學習筆記(深入)”;
- 需要臨時訪問一個可能還存在的對象
- 避免因引用導致對象無法釋放
建議:
- 使用前必須調用 lock() 獲取一個 shared_ptr
- 注意處理對象已經被釋放的情況
例如:
std::shared_ptr<int> sptr = std::make_shared<int>(30); std::weak_ptr<int> wptr = sptr; if (auto spt = wptr.lock()) { // 成功拿到 shared_ptr } else { // 對象已被釋放 }
常見用途:
- 緩存機制
- 觀察者模式中的訂閱者
- 圖結構中節點之間的弱連接
總結對比一下:
類型 | 所有權類型 | 是否可復制 | 是否可移動 | 是否支持自定義刪除器 |
---|---|---|---|---|
shared_ptr | 共享 | ? | ? | ? |
unique_ptr | 獨占 | ? | ? | ? |
weak_ptr | 觀察 | ?(復制不影響引用計數) | ? | 否 |
總的來說,unique_ptr 是首選,因為它效率高、語義明確;當確實需要共享時才使用 shared_ptr;而 weak_ptr 則用于協助打破循環引用或實現觀察機制。
基本上就這些,選對指針類型能讓代碼更安全、更高效。