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

從零手寫 C++ 智能指針:引用計數、拷貝語義與模板泛化

     編輯:關於C++

對話式推導:為什麼需要智能指針?

C++ 無內建垃圾回收,但提供構造/析構函數成對調用機制。
包裝裸指針:構造時接管所有權,析構時 delete。
再添加 operator* 使其像原生指針一樣使用。

缺失的拷貝控制

默認淺拷貝導致雙重 delete。
選項 1:深拷貝(memcpy 或拷貝構造)——對含指針成員的類失效。
選項 2:共享所有權 + 引用計數。

引用計數智能指針實現


template 
class SharedPtr {
    T* ptr;
    int* count; // 共享計數器
public:
    explicit SharedPtr(T* p = nullptr) : ptr(p), count(new int(1)) {}
    
    SharedPtr(const SharedPtr& rhs) : ptr(rhs.ptr), count(rhs.count) {
        ++(*count);
    }
    
    ~SharedPtr() {
        if (--(*count) == 0) {
            delete ptr;
            delete count;
        }
    }
    
    SharedPtr& operator=(const SharedPtr& rhs) {
        if (this != &rhs) {
            if (--(*count) == 0) { delete ptr; delete count; }
            ptr = rhs.ptr; count = rhs.count; ++(*count);
        }
        return *this;
    }
    
    T& operator*() const { return *ptr; }
    T* operator->() const { return ptr; }
    T* get() const { return ptr; }
    int use_count() const { return *count; }
};

繼承帶來的挑戰


class Base {};
class Derived : public Base {};

SharedPtr pb;
SharedPtr pd;
pb = pd; // 需支持派生到基類隱式轉換

簡單模板無法直接處理。boost::shared_ptr (現 std::shared_ptr) 通過類型擦除、轉換構造函數模板完美解決。

核心啟示

智能指針本質是「資源獲取即初始化」(RAII) 模式的極致應用。
C++ 程序員必須具備:
1. 不依賴語言內建 GC,自行管理資源生命周期。
2. 掌握 RAII、引用計數、移動語義等進階技巧。
3. 優先使用標準庫 std::shared_ptr/std::unique_ptr,必要時參考其設計原理自行擴展。

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