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

Spear Parser 核心組件解析(一):智慧指標 RCObject 與 RCIPtr 實作詳解

     編輯:關於C語言

前言

Spear Parser 是 Collins Model 1 解析模型的開源實作,包含訓練與解碼完整流程,適合作為自然語言處理統計解析的入門代碼庫。本系列將從底層輔助類別切入,第一篇剖析其智慧指標實作:RCObject(引用計數基類)與 RCIPtr(智慧指標模板)。

一、智慧指標設計動機

C++ 裸指標易造成記憶體洩漏、懸空指標、重複釋放等問題。智慧指標透過 RAII(資源獲取即初始化)自動管理物件生命週期,核心機制為引用計數:

  • 建立/複製指標時計數 +1。
  • 銷毀/重置指標時計數 -1。
  • 計數歸零時自動 delete 物件。

二、RCObject:可被智慧指標管理的基類

class RCObject {
public:
    void addReference();      // 計數 +1
    void removeReference();   // 計數 -1,歸零時 delete this
protected:
    RCObject();                           // 預設建構
    RCObject(const RCObject& rhs);        // 複製建構(不複製計數)
    RCObject& operator=(const RCObject&); // 指派(不複製計數)
    virtual ~RCObject() = 0;              // 純虛析構,強制繼承者實作
public:
    unsigned short refCount;              // 公開計數器(供 RCIPtr 直接存取)
};

inline RCObject::RCObject() : refCount(0) {}
inline RCObject::RCObject(const RCObject&) : refCount(0) {}
inline RCObject& RCObject::operator=(const RCObject&) { return *this; }
inline RCObject::~RCObject() {}

inline void RCObject::addReference() { ++refCount; }
inline void RCObject::removeReference() { if (--refCount == 0) delete this; }

關鍵設計點

  1. 複製/指派不複製計數:新物件獨立計數,避免邏輯錯亂。
  2. 純虛析構:確保衍生類別有虛析構函數,正確釋放資源。
  3. 公開 refCount:讓 RCIPtr 直接操作,省去友元聲明,簡化模板實作。
  4. removeReference 中 delete this:物件自我銷毀,要求物件必須以 new 建立於堆疊。

三、RCIPtr:智慧指標模板實作

template <class T>
class RCIPtr {
public:
    explicit RCIPtr(T* realPtr = 0);
    RCIPtr(const RCIPtr& rhs);
    ~RCIPtr();
    RCIPtr& operator=(const RCIPtr& rhs);
    T* operator->() const;
    T& operator*() const;
    void clear() { *this = RCIPtr<T>(0); }
private:
    T* pointee;
    void init() { if (pointee != 0) pointee->addReference(); }
};

核心成員函數實作

template <class T>
RCIPtr<T>::RCIPtr(T* realPtr) : pointee(realPtr) { init(); }

template <class T>
RCIPtr<T>::RCIPtr(const RCIPtr& rhs) : pointee(rhs.pointee) { init(); }

template <class T>
RCIPtr<T>::~RCIPtr() { if (pointee != 0) pointee->removeReference(); }

template <class T>
RCIPtr<T>& RCIPtr<T>::operator=(const RCIPtr& rhs) {
    if (pointee != rhs.pointee) {
        if (pointee != 0) pointee->removeReference();
        pointee = rhs.pointee;
        init();
    }
    return *this;
}

運算子重載

  • operator->()、operator*():透明轉發給內部裸指標,使用體驗與原生指標一致。
  • clear():歸零指標,釋放原物件引用。

四、使用範例

class BankEdge : public RCObject { /* 業務邏輯 */ };

RCIPtr<BankEdge> head;           // 相當於 BankEdge* head
head = new BankEdge();           // 計數 = 1
RCIPtr<BankEdge> another = head; // 計數 = 2
head->someMethod();              // 透明呼叫
head.clear();                    // 計數 -1,another 仍持有

五、現代 C++ 對比與啟示

特性RCIPtr (Spear)std::shared_ptr (C++11)
引用計數位置物件內部控制區塊(分離)
支援非繼承類別否(須繼承 RCObject)是
執行緒安全否控制區塊原子操作
自定義刪除器否支援
循環引用處理無搭配 weak_ptr

Spear 的實作極簡輕量,適合嵌入式或不想引入標準庫開銷的場景;現代專案建議優先使用 std::shared_ptr / std::unique_ptr。

結語

RCObject + RCIPtr 展示了經典內建引用計數智慧指標的精髓:以極少代碼實現自動記憶體管理。理解其「計數歸零自我刪除」與「複製共享所有權」的語意,對掌握現代 C++ 智慧指標內部機制大有裨益。

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