首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++11 智能指標完全指南:從 auto_ptr 到 unique_ptr、shared_ptr 與 weak_ptr

     編輯:C++ 入門

前言

智能指標是現代 C++ 資源管理的核心工具,C++11 引入了三種新型智能指標(unique_ptr、shared_ptr、weak_ptr),並棄用了早期的 auto_ptr。本文系統梳理四種智能指標的特性、適用場景與最佳實踐,並附上編譯環境配置指南。

編譯環境準備(以 Ubuntu 為例)

使用 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

1. auto_ptr(已棄用)

auto_ptr 是 C++98 為推廣 RAII 引入的首個智能指標,但存在嚴重缺陷:

  • 複製即移動:複製構造/賦值會轉移所有權,導致來源指標變空,不符合 STL 容器要求元素可複製、可賦值的規範,故不可存入容器。
  • 無法管理陣列:析構時固定呼叫 delete,無法自定義刪除器,不支援 delete[]。

結論:C++11 標準已棄用,C++17 移除,請勿在新代碼中使用。

2. unique_ptr(獨占所有權)

專為取代 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(); // 正常訪問

3. shared_ptr(共享所有權)

引入控制塊實現引用計數,允許多指標共享同一物件:

  • 執行緒安全的引用計數:控制塊計數器為原子操作,但指向物件本身的存取仍需外部同步。
  • 自定義刪除器與配置器:支援 make_shared 一次性分配物件與控制塊,提升效率並減少記憶體碎片。
  • 循環引用風險:兩物件互相持有 shared_ptr 會導致計數永不歸零,造成記憶體洩漏。
auto ptr1 = std::make_shared<A>();
auto ptr2 = ptr1; // 計數 +1
// 離開作用域自動釋放

4. weak_ptr(打破循環引用)

不增加引用計數,僅觀察 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

掌握智能指標的核心在於理解所有權語義與生命週期管理,合理選擇能讓資源管理更安全、代碼更清晰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved