用C/C++设计Lu结构、字典、类等高级数据类型(一)

2014-11-24 08:11:15 · 作者: · 浏览: 2

欢迎访问 Lu程序设计

用C/C++设计Lu结构、字典、类等高级数据类型

1 说明

本文没有直接给出演示例子,而是对Lu系统扩展库LuSystem实现的结构、字典、类等高级数据类型做说明,但你仍然需要下载Lu32脚本系统,并下载软件包lu1code.rar,LuSystem的源代码就在这个软件包中,源代码中用到的Lu核心库函数仍然参考Lu编程指南。由于LuSystem是一个Lu扩展动态库,你可能还要参考Lu扩展动态库说明。

本文假定你已经阅读了本教程系列的前面的内容,对涉及到的Lu基本数据类型、Lu键树、以#开头的标识符(字符串)确定的唯一的整数等内容不再重复说明。

2 关于Lu系统扩展库LuSystem

LuSystem32.dll是一个Lu系统扩展动态库,包含一些增强Lu系统功能的函数、对系统内置类型的扩展以及一些新增数据类型等等。LuSystem不仅是对Lu系统的扩充,更在于演示Lu是极易扩充其功能的脚本,很少有脚本允许用户能方便地添加像字典、结构、类等高级的数据结构,但Lu允许,而且实现这些很容易,因而,LuSystem也是编程用户极佳的练手工具。

为了便于理解本文,可以先看一下头文件LuSystem32.h(包含了字典、结构、类等数据结构的定义)和该库的入口文件LuSystem32.cpp(定义了函数LuDll32,Lu扩展库唯一的输出函数)。

3 结构(struct)实现原理及难点分析

结构(struct)是一个线性表,可以存放若干任意的Lu数据。结构成员必须以#开头。结构成员的存储顺序(递增排列)与其定义顺序不一定相同,当然这并不影响使用。例如以下脚本代码:

!!!using("sys"); //使用命名空间sys
struct[#num, #姓名 : "luuu", #年龄].o[]; //函数o用于输出一个对象

结果(成员#num和#年龄没有赋值,故值为nil):

struct{#num : nil , #姓名 : luuu , #年龄 : nil}

从头文件LuSystem32.h中可找到的结构(struct)定义如下:

struct SStruct{		//结构
	luINT max;	//成员数目
	luVOID *Name;	//成员名字(递增排列以加快访问速度),由一个以#开头的标识符(字符串)确定的唯一的整数
	LuData *Member;	//成员
};


注意结构定义中,成员名字不是使用字符串,而是使用由该字符串确定的一个唯一整数来标识,显然这样访问速度更快,并且成员是递增排列的,更加快了访问速度;另外,结构成员是Lu基本数据类型,这样可以存储任意的数据,包括另一个结构对象,甚至是自身。

从结构的实现文件Struct.cpp中可以找到如下两个函数:

void _stdcall DelStruct(void *vStruct)	//删除一个结构
{
	SStruct *pSStruct;

	pSStruct=(SStruct *)vStruct;
	if(pSStruct->Name) delete[] pSStruct->Name;
	if(pSStruct->Member) delete[] pSStruct->Member;
	delete pSStruct;
}

void _stdcall SignKeyStruct(void *me)	//标记子键值(对象)
{
	SStruct *pSStruct;
	luINT i;

	pSStruct=(SStruct *)me;
	for(i=0;i
  
   max;i++)
	{
		pSignGoodObj(pSStruct->Member+i);	//用函数SignGoodObj标记子对象
	}
}
  


函数DelStruct用于删除一个结构对象,但DelStruct是由锁定键的类型函数LockKey(LuSystem中使用的是函数指针pLockKey,下同,不再一一说明)注册到Lu系统中由Lu来调用的。函数SignKeyStruct是由插入键值函数InsertKey注册到Lu系统中由Lu来调用的,该函数的作用是:当Lu垃圾收集器工作时,如果一个结构是有效的,则该结构成员也应该是有效的,故Lu垃圾收集器会调用函数SignKeyStruct对结构成员做标记。顺便说一下,Lu垃圾收集器使用标记清除算法。

查看文件LuSystem32.cpp,会发现定义了全局变量keyStruct用以标识结构对象,该变量的值作为一个键被LockKey加锁(从其初始值keyStruct=-123115开始加锁,不成功时keyStruct--,直至加锁成功),加锁成功后,键keyStruct就只能存储结构对象。函数LockKey同时指明了销毁结构对象的函数是DelStruct;结构对象的运算符重载函数是OpLockStruct。另外,文件LuSystem32.cpp中还定义了标识对象keyStruct的字符串"struct",该字符串被注册为Lu整数常量,在Lu源代码中可用new(sys::struct,... ...)申请该对象。

再来看结构的实现文件Struct.cpp,结构对象的运算符重载函数OpLockStruct在该文件中定义,重载了函数set、len、copy、new、oset、oget、o等函数,相信你会在下面找到这些函数的具体实现,参考LuSystem的说明,可以更好地理解这些函数。为了便于操作结构对象,还向Lu系统注册(参考文件LuSystem32.cpp中的SetFunction函数)了函数sys::struct(对应C++函数lu_NewStruct)、sys::struct_oset(对应C++函数lu_osetStruct)和sys::struct_oget(对应C++函数lu_ogetStruct);当然,重载函数new、oset和oget也能实现对应的功能,因为它们对应相同的C++函数。

在扩展库LuSystem中测试了结构的效率。

4 字典(dict)实现原理及难点分析

字典(dict)是一个可直接存取的双向链表(使用双向链表便于删除一个字典元素),可以存放若干任意的Lu数据。字典元素由“键-值”对组成,键只能是字符串,但值可以是任何Lu数据类型,包括另一个字典,甚至自身。例如以下脚本代码生成了一个字典a并初始化,然后又在字典a中添加了一个元素:

!!!using("sys");
main(:a)= a=dict["aa":1.2, "abc":"luuu"], a."姓名"="王刚", o[a];

结果:

dict{aa : 1.2 , abc : luuu , 姓名 : 王刚}

从头文件LuSystem32.h中可找到的字典(dict)定义如下:

struct SDictItem{		//字典元素结构
	wchar_t *KeyStr;	//键
	LuData KeyValve;	//值
	SDictItem *pAhead;	//前一结点
	SDictItem *pNext;	//后一结点
};
struct SDict{		//字典结构
	luKEY KeyDict;	//标识一个字典,将锁定该键以存放字典元素
	SDictItem MainSDI;	//字典元素头结点
};


查看文件LuSyste