c++++中的智能指針通過自動管理內存解決手動管理導致的內存泄漏和重復釋放問題。1. shared_ptr共享資源所有權,適用多指針共同管理同一資源的場景,但需避免循環引用;2. unique_ptr獨占資源所有權,不可復制只能移動,適合單一管理者,性能優于shared_ptr;3. weak_ptr作為shared_ptr的觀察者,不增加引用計數,用于解決循環引用或臨時訪問資源。應優先使用make_shared和make_unique創建智能指針以提高安全性。
c++中的智能指針主要是為了解決手動管理內存容易出錯的問題,比如忘記釋放內存導致內存泄漏,或者重復釋放同一塊內存造成崩潰。常見的智能指針有三種:shared_ptr、unique_ptr 和 weak_ptr。它們各自有不同的使用場景和特點。
shared_ptr:共享所有權的智能指針
shared_ptr 是一種可以多個指針共享同一塊內存資源的智能指針。它內部維護了一個引用計數,當最后一個 shared_ptr 被銷毀或重置時,才會真正釋放所管理的對象。
- 適用場景:當你希望多個對象共同擁有一個資源,且這個資源在所有擁有者都不再需要之后才被釋放。
- 注意事項:要小心循環引用問題,否則可能導致內存無法釋放。
- 基本用法:
- 使用 make_shared
() 創建一個 shared_ptr - 可以賦值給另一個 shared_ptr,引用計數自動增加
- 不建議直接使用裸指針構造 shared_ptr,容易出錯
- 使用 make_shared
舉個例子:
立即學習“C++免費學習筆記(深入)”;
auto ptr1 = std::make_shared<int>(10); auto ptr2 = ptr1; // 引用計數變為2
這時候,只有當 ptr1 和 ptr2 都被銷毀后,int 所占的內存才會被釋放。
unique_ptr:獨占所有權的智能指針
unique_ptr 表示對資源的唯一擁有權。它不能被復制,只能通過移動語義轉移所有權。這種方式保證了資源的安全性,避免了多指針同時管理同一資源帶來的風險。
- 適用場景:當你希望某個資源只由一個指針管理,不允許多個指針同時持有。
- 優點:性能比 shared_ptr 更高,因為沒有引用計數開銷。
- 限制:不能復制,只能移動(move)
常見操作:
- 創建方式通常是 std::make_unique
()(C++14起) - 如果想轉移所有權,必須用 std::move()
例如:
auto ptr1 = std::make_unique<int>(20); auto ptr2 = std::move(ptr1); // ptr1現在為空
這時,ptr1 已經不再擁有資源,訪問它會導致未定義行為。
weak_ptr:配合 shared_ptr 使用的弱引用指針
weak_ptr 并不真正“擁有”資源,它是對 shared_ptr 管理的對象的一種觀察者角色。它的存在不會影響引用計數,因此不會阻止資源被釋放。
- 適用場景:解決 shared_ptr 的循環引用問題,或者用于緩存、監聽等不需要長期持有資源的場合。
- 使用方法:通常從 shared_ptr 構造而來,在使用前需要調用 lock() 獲取一個臨時的 shared_ptr
舉個典型用法:
std::shared_ptr<int> sp = std::make_shared<int>(30); std::weak_ptr<int> wp = sp; if (auto temp = wp.lock()) { // temp是一個有效的shared_ptr,可以安全使用 } else { // 對象已經被釋放了 }
注意:每次調用 lock() 都會生成一個新的 shared_ptr,所以不要頻繁調用。
總結一下使用建議:
- 如果你只需要一個指針負責資源,用 unique_ptr
- 如果多個地方都需要用到同一個資源,用 shared_ptr
- 如果不想影響資源生命周期但又需要訪問對象,用 weak_ptr
- 盡量使用 make_shared 和 make_unique 來創建智能指針,避免裸指針操作
基本上就這些,理解清楚三者的區別和使用場景,就能避免很多內存管理上的坑。