Spear Parser(一):智能指针类

Spear Parser简介

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,记录学习进度,做个系列的学习笔记吧。看的时候是从上往下看的,记的时候就从下往上记,先讲讲一些周边的类,最后讲讲整体的实现思路。

这个部分讲的是Spear的一些辅助类,第一个就是智能指针类(Smart Pointer)。

智能指针类简介

智能指针是C++中一种常用的技术,主要用来防止一个指针指向一个不存在的对象,核心是控制一个对象的删除时机。具体介绍可以参考《C++ Primer》中的介绍,第四版中文版是在13.5.1的部分。

Spear中智能指针类的实现 

Spear中智能指针类的实现,主要有两个类,RCObject和RCIPtr。RCIPtr是一个具体智能指针的实现类,RCObject是它能够指向的所有对象的父类。RCObject其实就是封装了count的管理行为,以便RCIPtr能够使用use-count技术实现Smart Pointer。

RCObject的代码如下:

  
  
  
  
  1. class RCObject  
  2.  public
  3.   void addReference(); 
  4.   void removeReference(); 
  5.  protected
  6.   RCObject(); 
  7.   RCObject(const RCObject& rhs); 
  8.   RCObject& operator=(const RCObject& rhs); 
  9.   virtual ~RCObject() = 0; 
  10.  public
  11.   unsigned short refCount; 
  12. }; 
  13. inline RCObject::RCObject() 
  14.   : refCount(0){} // std::cout << "RCObject constr\n"; } 
  15. inline RCObject::RCObject(const RCObject&) 
  16.   : refCount(0){} // std::cout << "RCObject copy constr\n"; } 
  17. inline RCObject& RCObject::operator=(const RCObject&) 
  18.   return *this
  19. }   
  20. inline RCObject::~RCObject() {} 
  21. inline void RCObject::addReference()  
  22.   ++refCount; 
  23. inline void RCObject::removeReference() 
  24.   if (--refCount == 0) delete this

这段代码挺简单的,就是普通的构造,拷贝构造,赋值,析构,外加对refCount的操作。注意点就是removeReference时当refCount为0的时候就把当前的对象删除了,这个其实就是一个的Smart Pointer的实现思路。后续可以看到很多的类都继承RCObject,以便于能够用智能指针技术管理指向它们对象的指针。

RCIPtr是Smart Pointer的实现,主要就是拷贝构造,赋值运算符,析构函数的实现。同时,它还重载了各种==,!=的实现,但这些重载并不是重点。

RCIPrt的代码如下:

  
  
  
  
  1. template<class T> 
  2. class RCIPtr  
  3.  public
  4.   explicit RCIPtr(T* realPtr = 0); 
  5.   RCIPtr(const RCIPtr& rhs); 
  6.   ~RCIPtr(); 
  7.   RCIPtr& operator=(const RCIPtr& rhs); 
  8.   T* operator->() const
  9.   T& operator*() const
  10.   void clear() { 
  11.     *this = RCIPtr<T>(0); 
  12.   }; 
  13. private
  14.   T *pointee; 
  15.   void init() { 
  16.     if(pointee != 0) pointee->addReference(); 
  17.   } 
  18. }; 

核心代码的实现:

  
  
  
  
  1. template<class T> 
  2. RCIPtr<T>::RCIPtr(T* realPtr) 
  3.   : pointee(realPtr) 
  4. {  
  5.   init(); 
  6. template<class T> 
  7. RCIPtr<T>::RCIPtr(const RCIPtr& rhs) 
  8.   : pointee(rhs.pointee) 
  9. {  
  10.   init();  
  11. template<class T> 
  12. RCIPtr<T>::~RCIPtr() 
  13. {  
  14.   if(pointee != 0) pointee->removeReference();  
  15. template<class T> 
  16. RCIPtr<T>& RCIPtr<T>::operator=(const RCIPtr& rhs) 
  17.   if (pointee != rhs.pointee) {          
  18.     if(pointee != 0) pointee->removeReference();      
  19.     pointee = rhs.pointee; 
  20.     init(); 
  21.   } 
  22.   return *this

Spear 智能指针类的使用

RCIPtr<BankEdge> _head; 这个就可以看作:BankEdge * _head, 用法基本一样 _head-&gt;,*_head都可以像原来的指针那样用,因为都重载过了。

你可能感兴趣的:(智能指针,parser,collins,Spear,句法分析)