当创建一个字典(设字典指针为pSDict)时,先使用随机算法加锁一个私有键pSDict->KeyDict(参考Dict.cpp中的LockKeyDictItem函数),用于存放字典元素,然后将pSDict注册为keyDict类型的私有键。当往字典中存放字典元素(设字典元素指针为pSDictItem)时,将pSDictItem注册为pSDict->KeyDict类型的私有键,并将pSDictItem链接到pSDict->MainSDI。故定位字典元素a."me"(a为字典,"me"为字典元素)的操作为:根据a的指针和键keyDict找到a的结构(设为pSDict),然后根据字符串"me"和pSDict->MainSDI找到该字典元素。
从字典的实现文件Dict.cpp中可以找到如下三个函数:
void _stdcall DelDict(void *vDict) //删除一个字典
{
SDict *pSDict;
pSDict=(SDict *)vDict;
pLockKey(pSDict->KeyDict,NULL,OpLockDictItem); //删除字典所有元素
delete pSDict;
}
void _stdcall DelDictItem(void *vSDI) //删除一个字典元素
{
SDictItem *pSDI;
pSDI=(SDictItem *)vSDI;
pSDI->pAhead->pNext=pSDI->pNext;
if(pSDI->pNext) pSDI->pNext->pAhead=pSDI->pAhead;
if(pSDI->KeyStr) delete[] pSDI->KeyStr;
delete pSDI;
}
void _stdcall SignKeyDict(void *me) //标记子键值(对象)
{
SDictItem *pSDI;
pSDI=((SDict *)me)->MainSDI.pNext;
while(pSDI)
{
pSignGoodObj(&(pSDI->KeyValve)); //用函数SignGoodObj标记子对象
pSDI=pSDI->pNext;
}
}
函数DelDict用于删除一个字典对象,函数DelDictItem用于删除一个字典元素对象,但DelDict和DelDictItem都是由锁定键的类型函数LockKey注册到Lu系统中由Lu来调用的。函数SignKeyDict是由插入键值函数InsertKey注册到Lu系统中由Lu来调用的,该函数的作用是:当Lu垃圾收集器工作时,如果一个字典是有效的,则该字典元素也应该是有效的,故Lu垃圾收集器会调用函数SignKeyDict对字典元素做标记。
文件Struct.cpp中定义了字典的运算符重载函数OpLockDict,重载了函数len、new、oset、oget、o等函数,相信你会在下面找到这些函数的具体实现,参考LuSystem的说明,可以更好地理解这些函数。为了便于操作字典对象,还向Lu系统注册(参考文件LuSystem32.cpp中的SetFunction函数)了函数sys::dict(对应C++函数lu_NewDict)、sys::dict_oset(对应C++函数lu_osetDict)和sys::dict_oget(对应C++函数lu_ogetDict);当然,重载函数new、oset和oget也能实现对应的功能,因为它们对应相同的C++函数。此外,还注册了函数sys::dict_del(对应C++函数lu_dict_del)、sys::dict_clear(对应C++函数lu_dict_clear)和sys::dict_reverse(对应C++函数dict_reverse)。
在扩展库LuSystem中测试了字典的效率。
5 类(class)实现原理及难点分析
类(class)是一个具有数据成员和方法成员的自定义数据结构。类可以继承和派生,类的层次结构是一棵树。
(1)类定义:class{... ...}
class{#cMyClass: #cBase1, #cBase2, ... //定义类cMyClass,继承自cBase1和cBase2, ...
private: //私有数据成员
#pvMem1, #pvMem2, ...
method: //私有方法(私有函数成员)
#vmFun1 :@Fun1, #vmFun2 :@Fun2, ...
public: //公有数据成员
#plMem1, #plMem2, ...
method: //公有方法(公有函数成员)
#__init__ : @init, #__del__ : @delme, #lmFun1 :@fun1, #lmFun2 :@fun2, ...
};
类定义中,类名称、基类名称、成员及方法都是以#开头的标识符,不可重复。类名称在最前面,其次是基类名称;private和public的次序是任意的,且可多次定义;在private后定义的method为私有方法,在public后定义的method为公有方法,若method前面没有private和public,默认是公有方法;方法标识符后必须提供函数句柄。类成员的存储顺序与其定义顺序不一定相同。
#__init__和#__del__只可被定义为公有方法,其中#__init__用于定义构造函数,#__del__用于定义析构函数。若这两个方法被缺省,其函数句柄被自动指定为0。构造函数和析构函数只有一个参数,即对象本身。
若方法有不止一个参数,则方法被调用时,第一个参数总是传入对象本身,相当于C++的this指针。
约定:类名称以字母c开头;私有数据成员以pv开头;公有数据成员以pl开头;私有方法成员以vm开头;公有方法成员以lm开头。
(2)创建类对象:obj(pClass)
pClass是类定义的句柄。
创建类对象时,将自动调用每一个基类的构造函数#__init__初始化基类对象。对象被销毁时,将自动调用每一个基类的析构函数#__del__销毁基类对象。
语句 a.=b 将对象b的内容复制到对象a,要求a和b具有相同的类定义,若类定义中定义了方法#__copy__(有且只有2个参数),将自动调用该方法进行对象复制,否则仅依次复制类成员的值。
例如以下脚本代码:
!!!using("sys");
setA(p,x)= p.#a=x; //类方法定义
getA(p) = p.#a; //类方法定义
main(:a,b)=
a=class{#A,