智能指標是現代 C++ 資源管理的核心工具,C++11 引入了三種新型智能指標(unique_ptr、shared_ptr、weak_ptr),並棄用了早期的 auto_ptr。本文系統梳理四種智能指標的特性、適用場景與最佳實踐,並附上編譯環境配置指南。
使用 GCC 4.8 以上版本支援 C++11:
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-4.8 g++-4.8
編譯時指定標準:g++-4.8 -std=c++11
auto_ptr 是 C++98 為推廣 RAII 引入的首個智能指標,但存在嚴重缺陷:
delete,無法自定義刪除器,不支援 delete[]。結論:C++11 標準已棄用,C++17 移除,請勿在新代碼中使用。
專為取代 auto_ptr 設計,提供零開銷的獨占語義:
std::move 轉移所有權。unique_ptr<T[]>)或其他資源(如 FILE*、socket)。// 單一物件
std::unique_ptr<A> ptr1(new A());
std::unique_ptr<A> ptr2 = std::move(ptr1); // 所有權轉移
// 陣列支援
std::unique_ptr<A[]> arr(new A[10]);
arr[0].getvalue(); // 正常訪問
引入控制塊實現引用計數,允許多指標共享同一物件:
make_shared 一次性分配物件與控制塊,提升效率並減少記憶體碎片。shared_ptr 會導致計數永不歸零,造成記憶體洩漏。auto ptr1 = std::make_shared<A>();
auto ptr2 = ptr1; // 計數 +1
// 離開作用域自動釋放
不增加引用計數,僅觀察 shared_ptr 管理的物件:
shared_ptr,不影響計數。lock() 獲取臨時 shared_ptr,檢查物件是否仍存在。std::weak_ptr<A> wp = ptr1;
if (auto sp = wp.lock()) {
sp->do_something(); // 安全存取
}
| 場景 | 推薦選擇 |
|---|---|
| 獨占資源、單一擁有者 | unique_ptr |
| 多處共享、生命週期不確定 | shared_ptr + make_shared |
| 需觀察但不延長生命週期、打破循環引用 | weak_ptr |
| C++11 以前舊代碼維護 | 逐步遷移至 unique_ptr/shared_ptr |
掌握智能指標的核心在於理解所有權語義與生命週期管理,合理選擇能讓資源管理更安全、代碼更清晰。