欢迎访问 Lu程序设计
使用C/C++给静态类型数据添加运算符重载功能
1 说明
要演示本文的例子,你必须下载Lu32脚本系统。本文的例子需要lu32.dll、lu32.lib、C格式的头文件lu32.h,相信你会找到并正确使用这几个文件。
用C/C++编译器创建一个控制台应用程序,复制本文的例子代码直接编译运行即可。
2 关于运算符重载
在本教程系列的开始,介绍了Lu脚本的基本数据结构(详细参考Lu编程指南),即:
struct LuData{ //Lu基本数据结构。
luIFOR x; //luIFOR被定义为64位整数__int64,用于存放数据。对于动态数据类型,对象指针约定保存在x的前4个字节中。
luIFOR y; //存放数据。
luIFOR z; //存放数据。
luKEY VType; //luKEY被定义为32位整数__int32。扩展数据类型,决定重载函数,从而决定了对数据的操作方式。
luKEY BType; //基本数据类型,决定了Lu数据的结构。
};
基本数据类型BType决定了实际的数据结构,而扩展数据类型VType决定了重载函数。若要对某数据类型VType进行运算符重载,需要用函数LockKey对VType加锁,该函数定义如下:
int _stdcall LockKey(luKEY VType,void (_stdcall *DeleteKey)(void *),luOperator OpLock);
VType:被锁定的键的类型。VType>luPubKey_User(公有键、普通键)或者 VType
OpLock:luOperator类型的函数指针,用于对象(用指针标识)的运算符重载,该参数不可为NULL。解锁和加锁所用的OpLock函数必须相同。参考
[注1]。
如果加锁或解锁成功,该函数返回0,否则返回非0值。
[注1]:运算符重载函数luOperator函数格式如下(与Lu二级函数相比,仅多了一个参数theOperator):
//m指出数组Para的参数个数(也即操作数的个数,0表示1个,1表示2个,以此类推)。
//hFor为调用该函数的表达式句柄(与二级函数中的表达式句柄相同)。
//theOperator指出运算符的类型或操作类型:+、-、*、/、^、... ...。
LuData (_stdcall *luOperator)(luINT m,LuData *Para,void *hFor,int theOperator);
LuData _stdcall OpLock(luINT m,LuData *Para,void *hFor,int theOperator)
{
//... ...
switch(theOperator)
{
case 0: //重载运算符+
//... ...
case 1: //重载运算符-
//... ...
case 2: //重载运算符*
//... ...
case 3: //重载运算符%
//... ...
case 4: //重载运算符/
//... ...
... ...
}
}
如果不打算给加锁的键提供运算符或函数重载功能,须使用函数SetRunErr向Lu报告运行错误。
本文讨论使用C/C++给静态类型数据添加运算符重载功能。本文的例子是实现C/C++中的单字节字符类型 char(基本类型为 luStaData_int64,扩展类型为 key_char),但仅定义了部分运算。
3 代码
#include#include "lu32.h" #pragma comment( lib, "lu32.lib" ) luKEY key_char = luPoiKey_User-20; //标识char的私有键,将对其加锁 void _stdcall Del_char(void *me) //销毁char的函数,但什么也不做,只为了配合运算符重载,加锁键使用 { } LuData _stdcall OpLock_char(luINT m,LuData *Para,void *hFor,int theOperator) //char的运算符重载函数 { LuData a; switch(theOperator) { case 0: //重载运算符+ if(Para[0].BType!=luStaData_int64 || Para[1].BType!=luStaData_int64) goto err; //要求基本类型为整数 a.BType=key_char; a.VType=key_char; a.x=(char)((char)(Para[0].x)+(char)(Para[1].x)); break; case 1: //重载运算符- if(Para[0].BType!=luStaData_int64 || Para[1].BType!=luStaData_int64) goto err; //要求基本类型为整数 a.BType=key_char; a.VType=key_char; a.x=(char)((char)(Para[0].x)-(char)(Para[1].x)); break; case 2: //重载运算符* if(Para[0].BType!=luStaData_int64 || Para[1].BType!=luStaData_int64) goto err; //要求基本类型为整数 a.BType=key_char; a.VType=key_char; a.x=(char)((char)(Para[0].x)*(char)(Para[1].x)); break; case 3: //重载运算符% if(Para[0].BType!=luStaData_int64 || Para[1].BType!=luStaData_int64) goto err; //要求基本类型为整数 a.BType=key_char; a.VType=key_char; a.x=(char)((char)(Para[0].x)%(char)(Para[1].x)); break; case 4: //重载运算符/ if(Para[0].BType!=luStaData_int64 || Para[1].BType!=luStaData_int64) goto err; //要求基本类型为整数 a.BType=key_char; a.VType=key_char; a.x=(char)((char)(Para[0].x)/(char)(Para[1].x)); break; default: a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0; //没有重载该运算符或者函数,返回nil SetRunErr(1,L"char 无法识别的运算符!",theOperator,0,hFor); } return a; err: a.BType=luStaData_nil; a.VType=luStaData_nil;