題目要求設計 PtrT 類別,管理 T* 動態記憶體,支援 aT->f() 和 (*aT).f() 語法,離開作用域自動 delete。這正是 **RAII (Resource Acquisition Is Initialization)** 核心思想,現代 C++ 直接使用 std::unique_ptr。
template <typename T>
class PtrT {
T* ptr_;
public:
explicit PtrT(T* p = nullptr) : ptr_(p) {}
~PtrT() { delete ptr_; }
// 禁止複製 (C++11 =delete,C++03 私有未實作)
PtrT(const PtrT&) = delete;
PtrT& operator=(const PtrT&) = delete;
// 移動語義 (C++11)
PtrT(PtrT&& other) noexcept : ptr_(other.ptr_) { other.ptr_ = nullptr; }
PtrT& operator=(PtrT&& other) noexcept {
if (this != &other) { delete ptr_; ptr_ = other.ptr_; other.ptr_ = nullptr; }
return *this;
}
// 解參考與成員存取
T& operator*() const { return *ptr_; }
T* operator->() const { return ptr_; }
T* get() const { return ptr_; }
// 釋放擁有權
T* release() { T* p = ptr_; ptr_ = nullptr; return p; }
void reset(T* p = nullptr) { delete ptr_; ptr_ = p; }
};
// 使用範例
class T { public: void f() {} };
int main() {
PtrT<T> aT(new T);
aT->f(); // 呼叫 T::f()
(*aT).f(); // 同義
return 0; // aT 解構,自動 delete
}
delete ptr_: 保證離開作用域釋放,即使拋出例外。operator-> 回傳 T*: 讓 aT->f() 能編譯 (編譯器遞迴解參考直到原始指標)。operator* 回傳 T&: 支援 (*aT).f()。#include <memory>
int main() {
std::unique_ptr<T> aT = std::make_unique<T>(); // C++14
aT->f();
(*aT).f();
} // 自動釋放,支援移動、自定義刪除器、陣列版 unique_ptr<T[]>
new 裸露,異常安全。// 管理 malloc/free、FILE*、Windows HANDLE 等
auto deleter = [](FILE* f) { if (f) fclose(f); };
std::unique_ptr<FILE, decltype(deleter)> fp(fopen("a.txt", "r"), deleter);
掌握 RAII 與智慧指標,徹底告別記憶體洩漏與野指標,是現代 C++ 開發者的必修課。