auto_ptr(C++98)嘗試實現獨占所有權語義,但複製/賦值會轉移所有權,導致嚴重缺陷:
vector> )會導致元素變為空指針。delete vs delete[])。C++11 棄用,C++17 移除。請勿在新代碼中使用。
template
class auto_ptr {
T* ptr;
public:
explicit auto_ptr(T* p = nullptr) : ptr(p) {}
~auto_ptr() { delete ptr; }
// 複製構造:轉移所有權
auto_ptr(auto_ptr& other) : ptr(other.release()) {}
auto_ptr& operator=(auto_ptr& other) {
if (this != &other) reset(other.release());
return *this;
}
T& operator*() const { return *ptr; }
T* operator->() const { return ptr; }
T* get() const { return ptr; }
T* release() { T* old = ptr; ptr = nullptr; return old; }
void reset(T* p = nullptr) { if (ptr != p) { delete ptr; ptr = p; } }
};
核心機制:引用計數。多個 shared_ptr 共享同一控制塊,計數歸零時釋放資源。
T*)。shared_ptr 數量)weak_ptr 數量)deleter)allocator)shared_ptr p1(new T); // 計數=1
shared_ptr p2 = p1; // 計數=2
shared_ptr p3;
p3 = p1; // 計數=3
p1.reset(); // 計數=2
p2.reset(); // 計數=1
p3.reset(); // 計數=0 → 釋放對象
// make_shared:單次分配對象+控制塊,效率更高
auto p = make_shared(args...);
// 獲取裸指針(慎用)
T* raw = p.get();
// 自定義刪除器
shared_ptr p(new T, [](T* ptr){ /* custom delete */ });
| 指針類型 | 所有權 | 複製語義 | 典型用途 |
|---|---|---|---|
unique_ptr | 獨占 | 移動語義(不可複製) | 獨占資源、RAII、工廠返回 |
shared_ptr | 共享 | 複製增加計數 | 多對象共享、緩存、觀察者模式 |
weak_ptr | 弱引用(不增加強計數) | 可複製 | 打破循環引用、緩存、觀察者 |
shared_ptr,B 持有 A 的 shared_ptr → 永不釋放。解決:一方用 weak_ptr。shared_ptr p1(new T); shared_ptr p2(p1.get()); → 雙重釋放。永不從裸指針構造多個 shared_ptr。shared_ptr (C++17) 或自定義刪除器 shared_ptr(new T[n], default_delete()) 。this 指針構造 shared_ptr:繼承 enable_shared_from_this,用 shared_from_this()。auto_ptr 是歷史教訓:複製即轉移所有權 破壞了值語義。
shared_ptr 通過引用計數 + 控制塊 正確實現共享所有權,是現代 C++ 共享資源管理的標準工具。
最佳實踐:優先用 unique_ptr 表達獨占,需共享時用 shared_ptr,打破循環用 weak_ptr,永遠用 make_shared/make_unique 構造。