Spear Parser簡介ide
Spear Parser(如下簡稱Spear)包含了Collins Model 1的訓練部分,對於理解和實現Collins模型來講,是個很好的入門代碼。由於M Collins的thesis中提供的代碼只包含了Parsing的部分,並無Training的部分,因此直接看Parsing的代碼,理解起來可能有點費勁。而Dan Bikel的貌似有點龐大,對於入門來講,不必看得那麼複雜。因此,我就本着偷懶的原則,處處Google Collins Model的實現,找到了一個還算不錯的Spear.函數
Spear的介紹網址The Spear Parser,它是open-source的。學習
爲了更好地理解Spear,記錄學習進度,作個系列的學習筆記吧。看的時候是從上往下看的,記的時候就從下往上記,先講講一些周邊的類,最後講講總體的實現思路。this
這個部分講的是Spear的一些輔助類,第一個就是智能指針類(Smart Pointer)。spa
智能指針類簡介指針
智能指針是C++中一種經常使用的技術,主要用來防止一個指針指向一個不存在的對象,核心是控制一個對象的刪除時機。具體介紹能夠參考《C++ Primer》中的介紹,第四版中文版是在13.5.1的部分。對象
Spear中智能指針類的實現 繼承
Spear中智能指針類的實現,主要有兩個類,RCObject和RCIPtr。RCIPtr是一個具體智能指針的實現類,RCObject是它可以指向的全部對象的父類。RCObject其實就是封裝了count的管理行爲,以便RCIPtr可以使用use-count技術實現Smart Pointer。ci
RCObject的代碼以下:rem
- class RCObject
- {
- public:
- void addReference();
- void removeReference();
- protected:
- RCObject();
- RCObject(const RCObject& rhs);
- RCObject& operator=(const RCObject& rhs);
- virtual ~RCObject() = 0;
- public:
- unsigned short refCount;
- };
- inline RCObject::RCObject()
- : refCount(0){} // std::cout << "RCObject constr\n"; }
- inline RCObject::RCObject(const RCObject&)
- : refCount(0){} // std::cout << "RCObject copy constr\n"; }
- 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;
- }
這段代碼挺簡單的,就是普通的構造,拷貝構造,賦值,析構,外加對refCount的操做。注意點就是removeReference時當refCount爲0的時候就把當前的對象刪除了,這個其實就是一個的Smart Pointer的實現思路。後續能夠看到不少的類都繼承RCObject,以便於可以用智能指針技術管理指向它們對象的指針。
RCIPtr是Smart Pointer的實現,主要就是拷貝構造,賦值運算符,析構函數的實現。同時,它還重載了各類==,!=的實現,但這些重載並非重點。
RCIPrt的代碼以下:
- 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;
- }
Spear 智能指針類的使用
RCIPtr<BankEdge> _head; 這個就能夠看做:BankEdge * _head, 用法基本同樣 _head->,*_head均可以像原來的指針那樣用,由於都重載過了。