注意:std::auto_ptr 自 C++11 起被棄用,C++17 已移除。現代代碼請使用 std::unique_ptr(獨佔所有權)或 std::shared_ptr(共享所有權)。本文為歷史技術文獻保留,解析 auto_ptr 設計原理與 RAII 模式。
new 分配記憶體後,若後續程式碼拋出異常且未被捕獲,delete 永不執行,造成記憶體洩漏。將資源(記憶體、檔案句柄、鎖等)的生命週期綁定至物件生命週期:
auto_ptr 是標準庫早期為「獨佔所有權動態記憶體」提供的 RAII 包裝器。
template <class T>
class auto_ptr {
T* ptr;
public:
explicit auto_ptr(T* p = 0) : ptr(p) {}
~auto_ptr() { delete ptr; }
// 拷貝建構子:所有權轉移(修改來源!)
auto_ptr(auto_ptr& other) : ptr(other.ptr) { other.ptr = 0; }
// 賦值運算子:釋放舊資源,接管新資源
auto_ptr& operator=(auto_ptr& other) {
if (this != &other) {
delete ptr;
ptr = other.ptr;
other.ptr = 0;
}
return *this;
}
T& operator*() const { return *ptr; }
T* operator->() const { return ptr; }
T* get() const { return ptr; }
T* release() { T* t = ptr; ptr = 0; return t; }
void reset(T* p = 0) { delete ptr; ptr = p; }
};
auto_ptr<int> p1(new int(42));
auto_ptr<int> p2 = p1; // p1 變為空,p2 擁有所有權
// p1.get() == nullptr, p2.get() == 0x...
這打破了 C++ 「拷貝語意保持來源不變」的慣例,導致:
shared_ptr)。| 特性 | auto_ptr (C++98) | unique_ptr (C++11) | shared_ptr (C++11) |
|---|---|---|---|
| 所有權模型 | 複製即轉移(危險) | 移動語意轉移(安全) | 參考計數共享 |
| 容器相容 | ❌ | ✅ | ✅ |
| 陣列支援 | ❌ | ✅ (unique_ptr<T[]>) | ✅ (需自訂刪除器) |
| 自訂刪除器 | ❌ | ✅ | ✅ |
| 執行緒安全 | ❌ | ✅ (移動) | ✅ (控制塊原子操作) |
std::unique_ptr<T>,語法幾乎相同,但支援移動語意(std::move),編譯器會阻止錯誤的拷貝。std::shared_ptr<T>,注意循環引用問題(配合 weak_ptr 解決)。unique_ptr<T[]> 自動呼叫 delete[]。auto_ptr 是 C++ 邁向 RAII 與智慧指標的關鍵嘗試,其「複製即轉移」設計雖具創新性,卻違反直覺且難以正確使用。現代 C++ 以 unique_ptr/shared_ptr 徹底解決所有權管理問題,開發者應全面遷移至新標準,避免歷史包袱。