首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 智慧指標入門:實作簡易 PtrT 類別自動釋放記憶體 (RAII 模式)

     編輯:程式設計疑難解答

題目要求設計 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_: 保證離開作用域釋放,即使拋出例外。
  • 刪除複製建構/賦值: 防止雙重釋放 (double free)。
  • 實作 operator-> 回傳 T*: 讓 aT->f() 能編譯 (編譯器遞迴解參考直到原始指標)。
  • 實作 operator* 回傳 T&: 支援 (*aT).f()。

現代 C++ 最佳實踐

#include <memory>
int main() {
    std::unique_ptr<T> aT = std::make_unique<T>(); // C++14
    aT->f();
    (*aT).f();
} // 自動釋放,支援移動、自定義刪除器、陣列版 unique_ptr<T[]>
  • std::unique_ptr:單一擁有,零開銷,C++11 標準庫。
  • std::shared_ptr:共享擁有,控制塊引用計數,較重。
  • std::make_unique / make_shared:避免 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++ 開發者的必修課。

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