srilm 阅读文档7

XCount.h XCount.cc
文档作者:jianzhu
创立时间:08.09.08

--------------------------------------
1、基本类
--------------------------------------
   这两个文件定义了一个用于保存和管理次数(频数)的数据结构,该文件定义的
XCount类用于保存频数,当该频数的值小或等于unsigned short(or unsigned),则
将其保存直接保存到成员变量count中,并将成员变量indirect设为false。如果该频
数的值大于unsigned short(or unsigned),则通过调用成员函数getXCountTableIndex
来获得xcountTable中保存频数值的下标位置,将该位置保存到成语变量count中,而
将频数保存到xcountTable[count]单元中,同时将成员变量indirect设为true。
XCount类
   该类提供如下函数
   a) 构造函数
   b) 析构函数
   c) 拷贝构造函数
   d) 重载的赋值运算符
   e) 重载的+=运算符
   f) 重载的-=运算符
   g) cast运算符
--------------------------------------
2、函数功能解释
--------------------------------------
a) 构造函数
<src>
0  XCount::XCount(XCountValue value)
1           : indirect(false)
2  {
3      if (value <= XCount_Maxinline) {
4        indirect = false;
5      count = value;
6      } else {
7      indirect = true;
8      count = getXCountTableIndex();
9
10     xcountTable[count] = value;
11    }
12 }
</src>
    功能:带参数的构造函数,用于将value值保存到创建的对象中。
    
    细解:第1行通过成员初始化列表的方式将indirect初始化为false;
    第3-6行判断当前要保存的value值是否超过XCountIndex的表示范围,
    若没有超过则将indirect设为false,同时将value值保存到count中;
    第6-11行用于处理当value值超过XCountIndex表示范围的情况,这时
    将indirect设为true,同时通过调用getXCountTableIndex函数获取
    保存当前value值的xcountTable数组下标位置,将count值设为
    该下标,并将value保存到xcountTable中的对应单元处。
    getXCountTableIndex函数
    <src>
   0   XCountIndex
  1  XCount::getXCountTableIndex()
  2  {
    3    static Boolean initialized = false;
  4
    5    if (!initialized) {
    6      // populate xcountTable free list
  7      for (XCountIndex i = 0; i < XCount_TableSize; i++) {
   8         xcountTable[i] = freeList;
   9         freeList = i;
  10     }
  11
    12     initialized = true;
    13   }
  14
    15   Boolean xcountTableEmpty = (freeList == XCount_Maxinline);
    16   assert(!xcountTableEmpty);
  17
    18   XCountIndex result = freeList;
    19   freeList = xcountTable[freeList];
  20
    21   refCounts[result] = 1;
    22   return result;
  23 }
    </src>
    功能:用于获取当前xcountTable中可用的单元对应的下标,同时将refCounts对应单元初始化
    为1,表示引用次数为1。同时返回可用单元对应的下标。
    
    细解:
    第3-13行用于判断是否初始化了xcountTable,如未初始化,则对其进行初始化操作,以链表
    方式初始化,其中下标对应于链表的指针。freeList指向链表单元的最后一个单元,xcountTable[
    freeList]中保存的值为下一个可用单元的索引;
    第15-16行用于判断当前xcountTable是否已经填满,即没有可用单元;
    第18行将freeList值保存到result中,即当前可用的数组单元;
    第19行将freeList置为下一个可用的单元索引位置;
    第21行将对应单元被应用次数设为1;
    第22行返回可用的数组单元索引。
b) 析构函数
<src>
0  XCount::~XCount()
1  {
2      if (indirect) {
3      freeXCountTableIndex(count);
4      }
5  }
</src>
    功能:用于析构当前的XCount类
    
    细解:
    第2-4行判断indirect是否为true,若为true,则当前XCount中的值保存在xcountTable中,而count
    中保存的只是其对应的索引,同时refCount中记录了其对应值被引用的次数;
    因此第3行调用freeXCountTableIndex函数进行相应的资源回收操作。
    freeXCountTableIndex函数
    <src>
    0  void 
  1  XCount::freeXCountTableIndex(XCountIndex idx)
  2  {
    3    refCounts[idx] --;
    4    if (refCounts[idx] == 0) {
  5      xcountTable[idx] = freeList;
  6      freeList = idx;
    7    }
  8  }
    </src>
  功能:用于将idx对应的refCounts和xcountTable资源回收
  
  细解:第3行将refCounts对应的单元被引用计数减一;
  第4-7行处理refCounts引用计数为0后,xcountTable对应的资
  源回收操作。当refCounts对应单元的引用计数为0时,则需要
  将当前单元添加到可用单元中。首先通过第5行,将对应单元链
  接到可用单元列表中,然后通过第6行,将第一个可用单元置为
  当前刚被回收的单元。
  
c) 拷贝构造函数
<src>
0  XCount::XCount(const XCount &other)
1  {
2      indirect = other.indirect;
3      count = other.count;
4      if (indirect) {
5      refCounts[count] ++;
6      }
7  }
</src>
  功能:用于将当前创建的对象初始化为other
  
   细解:第2-3行初始化indirect和count两个成员变量
   第4-6行处理当indirect为true时,将refCounts[count]
   值增1,用于表示对应的xcountTable[count]单元中的值
   被一个新创建的对象所共享。
d) 重载的赋值运算符
<src>
0  XCount &
1  XCount::operator= (const XCount &other)
2  {
3      if (&other != this) {
4        if (indirect) {
5          freeXCountTableIndex(count);
6      }
7  
8      count = other.count;
9      indirect = other.indirect;
10
11     if (other.indirect) {
12         refCounts[other.count] ++;
13     }
14     }
15    return *this;
16 }
</src>
    功能:用于将当前other对象赋给当前对象
    
    细解:第3行判断是否存在自我赋值的情况,若是自我赋值,则直接
    运行第15行返回当前对象;否则判断当前对象的indirect是否为true,
    若为true,则调用freeXCountTableIndex函数对当前对象进行资源回收。
    第8-9行将count和indirect值初始化为other对应的值;第11-13行判断
    other.indirect是否为true,若为true则将refCounts对应的单元增1。
e) 重载的+=运算符
<src>
0  XCount & operator+= (XCountValue value)
1  { 
2    *this = (XCountValue)*this + value; 
3    return *this; 
4  }
</src>
    功能:将XCount对象中保存的值加上value值
    
    细解:第2行首先通过调用cast函数(XCountValue),获取当前
    对象对应的value值,然后将其与value值相加,并通过调用
    构造函数构造将相加结果保存的构造出的对象中,然后通过
    调用赋值运算符,将当前对象初始化为构造出的对象;
    第3行返回运算后的当前对象,同时在退出当前函数作用域后对
    构造处的临时对象进行析构操作;
<src>
0  XCount & operator+= (XCount &value)
1  {
2    *this = (XCountValue)*this + (XCountValue)value;
3    return *this;
4  }
</src>
    该函数和上一个重载的+=运算符函数大同小异,只是调用了两次
    cast运算符,其余一样。
    
f) 重载的-=运算符
<src>
0  XCount & operator-= (XCountValue value)
1  { 
2    *this = (XCountValue)*this - value; 
3    return *this; 
4  }
</src>
    该函数和上一个重载的+=运算符函数大同小异。
    
<src>
0   XCount & operator-= (XCount &value)
1  {
2    *this = (XCountValue)*this - (XCountValue)value; 
3    return *this; 
4  }
</src>
    该函数和上一个重载的+=运算符函数大同小异。
    
g) cast运算符
<src>
0  XCount::operator XCountValue() const
1  {
2      if (!indirect) {
3      return count;
4      } else {
5      return xcountTable[count];
6      }
7  }
</src>
    功能:用于返回当前对象中保存的value值
    
    细解:第2-4行处理当indirect为false的情况,即count中保存的
    即为频率值,而非索引。
    第4-6行处理indirect为true的情况,即count中保存的是索引,则
    返回xcountTable[count]的值。
  
--------------------------------------
知识点:
--------------------------------------
1、链表的数组表示
       一般情况下链表可以用指针的方式来实现,但通过数组下标的方式
   也可以实现链表的结构,如该类通过将xcountTable和freeList结合实现
   了一个简单的链表。
2、对象赋值
       *this = (XCountValue)*this + (XCountValue)value;
   上述语句中由于XCount类未提供类似于XCount & operator=
   (XCountValue Value);这样的重载赋值运算符,因此执行以下操作时:
       *this = value;
   发生以下操作过程
       XCount(XCountValue value = 0);            // 构建临时对象
       XCount & operator= (const XCount &other); // 调用赋值操作符函数
       ~XCount();                                // 析构临时对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值