FORCAL中的对象、函数和模块

来源:互联网 发布:led center软件下载 编辑:程序博客网 时间:2024/05/17 06:36

欢迎访问 Forcal数学软件

FORCAL中的对象、函数和模块

目  录

1 Forcal中的对象
2 Forcal中的函数

3 Forcal中的模块
4 Forcal中的类模块5 静态类成员
6 类成员函数
7 虚函数与多态性

    Forcal的核心库Forcal32.dll中没有类和对象的概念,但Forcal32.dll对功能扩展提供了很好的支持,利用Forcal32.dll本身提供的编程功能和Forcal扩展动态库FcData及MForcal,很容易地构造出类及对象的概念。由于动态编译的特点,Forcal完全可以看作是面向对象的。

    要全面理解和演示本文的例子,需要下载作者的另外两个程序MForcal和OpenFC,MForcal可对Forcal源代码进行模块化编译,OpenFC全面演示了Forcal的应用。可以从作者网站、天空软件站、华军软件园等多家站点下载到这两个程序。

1 Forcal中的对象 [返回页首]

    使用FcData中的类定义可以创建对象,实际上,在Forcal中一切数据都可以看作是对象,而任何一个函数或表达式都可以看作是类或对象的成员函数。对对象进行合理的分类可以更好地使用它们。根据使用特点,Forcal中的对象可以分为三类:Forcal内置数据对象、非FcData类对象、FcData类对象。

1.1 Forcal内置数据对象

    Forcal中有三种表达式:整数、实数和复数表达式,分别对整数、实数和复数数据进行运算处理,整数、实数和复数即Forcal的三种内置数据对象。Forcal内置数据对象的成员函数是一些常用的数学函数或自定义表达式。Forcal内置数据对象可以直接存取,而且可以用等号运算符进行赋值。例如:

(2).sin();        //sin(2);
x.cos().sin();   
//sin[cos(x)];
x=(2).sin();      //x=sin(2);

1.2 非FcData类对象

    FcData中所有的数据都用函数new申请,这些数据可以是简单数据、数组、类及外部数据类型等,所有的数据都用一个指针,即一个4字节整数进行标识。所有的FcData数据都是对象。FcData对象只能用专用的成员函数进行存取,不能用等号运算符进行赋值。如果一个函数或表达式遇到不可识别的FcData对象,将返回一个运行错误。

    FcData对象可分为两类:非FcData类对象和FcData类对象。进行这种分类的依据仅仅是因为FcData类对象是一种特殊的数据。

    除了FcData之外,其他Forcal扩展动态库中也有一些函数可以创建对象,这些对象也是非FcData类对象。非FcData类对象也包括Forcal内置字符串。简单地讲,除了Forcal内置数据对象和FcData类对象,其余的都是非FcData类对象。例如:

i: (:x)= x=new(int),           //申请一个整数对象x
         x
.set(99),            //调用整数对象的成员函数set给x赋值
         x.get();
              //通过整数对象的成员函数get获得x的值
i: "Hello !"
.OutNStr[];        //字符串对象及成员函数调用

    注意:除了Forcal内置数据对象以外,其他的对象只能用专用的成员函数进行存取,不能用等号运算符进行赋值。非FcData类对象和FcData类对象都是如此。

1.3 FcData类对象

    FcData类由关键字cdef定义,如:

Cperson=new(cdef:"姓名","性别","年龄");    //定义一个类,描述一个人的简单信息,有三个类成员

    该函数返回一个类指针Cperson,通过该类指针,使用关键字class可创建一个类对象。如:

person=new(class,Cperson);                //创建一个类对象person,但未对类成员进行赋值

    给类对象赋值:

person."姓名".SetCM[new(char_s,EndType,"王强"),true];
person."性别".SetCM[new(char_s,EndType,"男"),true];
person."年龄".SetCM[new(int,23),true];

    也可以在申请类对象时直接赋值:

person=new{class,Cperson:
    "姓名",new(char_s,EndType,"王强"),
    "性别",new(char_s,EndType,"男"),
    "年龄",new(int,23)
};

    获得并输出类对象的值:

person.BCM("姓名").OutStr[true];
person.BCM("性别").OutStr[true];
person."年龄".get();

    完整的例子如下所示:

i:(::Cperson)= Cperson=new(cdef:"姓名","性别","年龄");    //定义一个类,描述一个人的简单信息,有三个类成员

i:(::Cperson,person)= person=new(class,Cperson);         //创建一个类对象person,但未对类成员进行赋值

i:(::person)=
{
    person."姓名".SetCM[new(char_s,EndType,"王强"),true],
    person."性别".SetCM[new(char_s,EndType,"男"),true],
    person."年龄".SetCM[new(int,23),true]
};

i:(::person)= person.BCM("姓名").OutStr[];
i:(::person)= person.BCM("性别").OutStr[];
i:(::person)= person."年龄".get();

    FcData中类的成员都是公有数据,每一个数据可看作一个对象,所有的数据都通过特定的函数进行存取。要想使用私有数据和函数,把类放到模块(称类模块)中就可以了。FcData中的类及成员之间有自然的继承性,而且可以通过循环链表实现相互继承。FcData中的类层次关系是一棵树或一个连通图。缺省情况下,在FcData中销毁一个类对象时,所有的基类对象也一并销毁,在类对象以循环链表的方式相互继承的情况下也是如此。

2 Forcal中的函数 [返回页首]

    本文中,为了说明的方便,我们将自定义的表达式也称为函数。

    可按不同的分类方法对Forcal中的函数进行分类。

    按所处理的数据类型不同,可分为整数函数、实数函数和复数函数三种,分别存在于整数表达式、实数表达式和复数表达式中。

    按来源不同,可分为Forcal内置函数(包括一级函数和二级函数)、外部二级函数(通过Forcal扩展模块添加的函数)、用户自定义函数。

    按运算速度不同可分为一级函数和二级函数,一级函数都是Forcal内置的,二级函数有些是内置的,但更多的是外置的。

    按是否存在递归可分为递归函数和非递归函数。

    按函数属性可分为模块私有函数和模块公有函数,私有函数只能被本模块的表达式所访问,公有函数可被任意模块的函数所访问。

    按所处理的对象不同,称为某种对象的成员函数。

    本文主要讨论对象的成员函数。如果某个成员函数不能处理所传入的对象参数,将产生一个运行错误。

2.1 可处理所有对象的函数

    纯粹的数值运算函数,如sin、cos等,把所有的对象都看作一个数值来进行运算,因而这类函数可处理所有的对象,是所有对象的成员函数。

2.2 处理特定对象的函数

    某些函数只能处理一些特定的对象,是这些对象的专用成员函数。如Forcal扩展库OpenFcGl中的函数gluSphere,只能处理二次曲面对象,因而gluSphere是二次曲面对象的专用成员函数。

2.3 处理某些对象的函数

    有些函数能处理多种类型的对象,如函数OutStr可处理Forcal内置字符串对象和FcData字符数组对象,函数copy可处理绝大多数的FcData数据对象。

3 Forcal中的模块 [返回页首]

    Forcal模块化编译运行库MForcal可对源代码进行模块化编译,例如:

      #MODULE#                         //定义一个子模块,模块名为Module1;
        i:set(x::add)= add=x;         
//模块号为负,只能被该模块的表达式所访问;
        i:get(::add)= add;            
//模块号为负,只能被该模块的表达式所访问;
        ~i:Module1_set(x)= set(x);  
   //模块号为正,任意模块包括本模块均可访问;
        ~i:Module1_get()= get();      
//模块号为正,任意模块包括本模块均可访问;
      #END#            
               //子模块定义结束,可缺省;

      #MODULE#            
            //定义一个子模块,模块名为Module2;
        i:set(x::add)= add=x;         
//模块号为负,只能被该模块的表达式所访问;
        i:get(::add)= add;            
//模块号为负,只能被该模块的表达式所访问;
        ~i:Module2_set(x)= set(x);  
   //模块号为正,任意模块包括本模块均可访问;
        ~i:Module2_get()= get();       
//模块号为正,任意模块包括本模块均可访问;
      #END#            
               //子模块定义结束,不可缺省;

      i:set(x::add)= add=x;           
//主模块中的表达式。
      i:get(::add)= add;            
  //主模块中的表达式。
      i:set(33);               
       //主模块中的表达式。

      Module1_set(11);               
 //主模块中的表达式。
      Module2_set(22);               
 //主模块中的表达式。
      Module1_get();               
   //主模块中的表达式。
      Module2_get();               
   //主模块中的表达式。

      get();                           //主模块中的表达式。

    建议模块公有表达式的命名格式为模块名加函数名,即:ModuleName_FunctionName。如果采用模块命名空间,则输出函数可以采用较短的函数名。

4 Forcal中的类模块 [返回页首]

    FcData类和MForcal模块结合称为类模块,可实现更为强大的功能。

    在类模块(假设名称为:Person)中一般应至少定义三个函数:

1)实现类定义的函数:NewCPerson(:static,_CPerson,free:CPerson)

    该函数为私有函数,一般设置该函数不能自动执行,只能被其他表达式调用执行。申请的类定义保存在模块变量CPerson中,该变量只能在本模块中使用。类定义只保存一个副本即可。

    为了在销毁表达式时能自动销毁对象CPerson,须用自动静态变量_CPerson保存对象CPerson。当然这并不是必须的,因为FcData有自动垃圾回收的功能。

2)初始化模块函数:InitPerson(:static:nFree)

    该函数为私有函数,允许自动执行,更好的实现是设置为编译后立即执行(表达式名称前加编译符“!”),且仅需执行一次。

    在初始化过程中,要调用函数NewCPerson申请类定义,并将当前调用函数DeleteAllFCD()的次数保存到模块变量nFree中,该次数由函数nDeleteAllFCD()获得。由于用户可在任意的时刻用函数DeleteAllFCD()销毁所有的FcData数据,则类定义CPerson也将被销毁。比较两次调用函数nDeleteAllFCD()的返回值,可以知道类定义CPerson在这两次调用期间是否被销毁,若两个返回值相等,表示没有销毁,否则已被销毁。为了以后能检测CPerson是否被销毁,在初始化函数中需用模块变量nFree保存函数nDeleteAllFCD()的返回值。 若类定义CPerson被销毁,需要重新执行函数NewCPerson

3)实现类对象的函数:NewPerson(:person:CPerson,nFree)

    该函数为全局函数,一般设置该函数不能自动执行,只能被其他表达式调用。每次调用该函数,均创建一个类Person的实例(对象)。由NewPerson返回的对象p,不用时须用调用函数delete(p)销毁。在该函数中要检查类定义CPerson是否被销毁,方法是比较nFree是否与nDeleteAllFCD()相等,若相等,则没有销毁,否则已销毁,须重新执行函数NewCPerson

4.1 Person类的模块实现

#MODULE#                                     //定义一个模块,模块名为Person,描述一个人的姓名、性别和年龄 。类Person是安全的,不会因为DeleteAllFCD()而停止工作

i::NewCPerson(:static,_CPerson,free:CPerson)= //定义 类CPerson,该函数不会自动执行
{
    if[free,delete(_CPerson),return(0)],
      //销毁表达式时,自动销毁申请的对象
    CPerson=new(cdef:"姓名","性别","年龄"),
    _CPerson=CPerson
};

i:!InitPerson(:static:nFree)=          //初始化模块Person,nFree用于标记类定义CPerson是否被函数DeleteAllFCD()销毁
{
    if{!static,static=1,nFree=nDeleteAllFCD(),NewCPerson()}
};

~i::NewPerson(:person:CPerson,nFree)=  //申请类Person的对象,该函数不会自动执行,全局函数
{
    person=nDeleteAllFCD(),
    if{nFree!=person,nFree=person,NewCPerson()},
   //如果类定义CPerson已被函数DeleteAllFCD()销毁重新NewCPerson()
    person=new(class,CPerson),
    person."姓名".SetCM[new(char_s,11),true],
    person."性别".SetCM[new(char_s,3),true],
    person."年龄".SetCM[new(int),true],
    person
};

#END#

i:(::person)=
{
    person=NewPerson(),
    person.BCM("姓名").FCDstrcpy("王强",false),
    person.BCM("性别").FCDstrcpy("男",false),
    person.BCM("年龄").set(22)
};

i:(::person)= person.BCM("姓名").OutStr[];
i:(::person)= person.BCM("性别").OutStr[];
i:(::person)= person.BCM("年龄").get();
i:(::person)= delete(person);

4.2 Student类的模块实现,继承自Person

#MODULE#                                     //定义一个模块,模块名为Person,描述一个人的姓名、性别和年龄 。类Person是安全的,不会因为DeleteAllFCD()而停止工作

i::NewCPerson(::CPerson)=              //定义 类CPerson,该函数不会自动执行
{
    CPerson=new(cdef:"姓名","性别","年龄")
};

i:InitPerson(:static:CPerson,nFree)=   //初始化模块Person,nFree用于标记类定义CPerson是否被函数DeleteAllFCD()销毁
{
    if{!static,static=1,nFree=nDeleteAllFCD(),NewCPerson()}
};

~i::NewPerson(:person:CPerson,nFree)=  //申请类Person的对象,该函数不会自动执行,全局函数
{
    person=nDeleteAllFCD(),
    if{nFree!=person,nFree=person,NewCPerson()},
   //如果类定义CPerson已被函数DeleteAllFCD()销毁重新NewCPerson()
    person=new(class,CPerson),
    person."姓名".SetCM[new(char_s,11),true],
    person."性别".SetCM[new(char_s,3),true],
    person."年龄".SetCM[new(int),true],
    person
};

#END#

#MODULE#                                     //定义一个模块,模块名为Student,描述一个学生的信息,继承自Person类。类Student是安全的,不会因为DeleteAllFCD()而停止工作

i::NewCStudent(::CStudent)=            //定义 类CStudent,该函数不会自动执行
{
    CStudent=new(cdef:"Person","班级","爱好")
};

i:InitStudent(:static:CStudent,nFree)=   //初始化模块Student,nFree用于标记类定义CStudent是否被函数DeleteAllFCD()销毁
{
    if{!static,static=1,nFree=nDeleteAllFCD(),NewCStudent()}
};

~i::NewStudent(:student:CStudent,nFree)=  //申请类Student的对象,该函数不会自动执行,全局函数
{
    student=nDeleteAllFCD(),
    if{nFree!=student,nFree=student,NewCStudent()},
   //如果类定义CStudent已被函数DeleteAllFCD()销毁重新NewCStudent()
    student=new(class,CStudent),
    student."Person".SetCM[NewPerson(),true],
    student."班级".SetCM[new(char_s,10),true],
    student."爱好".SetCM[new(char_s,10),true],
    student
};

#END#

i:(::student)=
{
    student=NewStudent(),
    student.BCM("姓名").FCDstrcpy("王强",false),
    student.BCM("性别").FCDstrcpy("男",false),
    student.BCM("年龄").set(22),
    student.BCM("班级").FCDstrcpy("二年级",false),
    student.BCM("爱好").FCDstrcpy("足球",false)
};

i:(::student)= student.BCM("姓名").OutStr[];
i:(::student)= student.BCM("性别").OutStr[];
i:(::student)= student.BCM("年龄").get();
i:(::student)= student.BCM("班级").OutStr[];
i:(::student)= student.BCM("爱好").OutStr[];
i:(::student)= delete(student);

5 静态类成员 [返回页首]

    静态类成员只能有一个备份存在,不论这个类创建了多少个对象。每个对象共享这一变量备份。如下例:

#MODULE#                                     //定义一个模块,模块名为Person,描述一个人的姓名、性别 、年龄和省份,其中省份是静态类成员。

i::NewCPerson(:static,xx,yy,free:CPerson,province)= //定义 类CPerson,该函数不会自动执行
{
    if[free,delete(xx),delete(yy),return(0)],
       //销毁表达式时,自动销毁申请的对象
    CPerson=new(cdef:"姓名","性别","年龄","省份"),xx=CPerson,
    province=new(char_s,EndType,"山东省"),yy=province
};

i:InitPerson(:static:CPerson,nFree)=   //初始化模块Person,nFree用于标记类定义CPerson是否被函数DeleteAllFCD()销毁
{
    if{!static,static=1,nFree=nDeleteAllFCD(),NewCPerson()}
};

~i::NewPerson(:person:CPerson,province,nFree)=   //申请类Person的对象,该函数不会自动执行,全局函数
{
    person=nDeleteAllFCD(),
    if{nFree!=person,nFree=person,NewCPerson()},
 //如果类定义CPerson已被函数DeleteAllFCD()销毁重新NewCPerson()
    person=new(class,CPerson),
    person."姓名".SetCM[new(char_s,11),true],
    person."性别".SetCM[new(char_s,3),true],
    person."年龄".SetCM[new(int),true],
    person."省份".SetCM[province,true],
  //给类成员"省份"赋值
    person."省份".SetCM[false,false],
    //设置类成员"省份"的属性为不能自动删除,即成为静态类成员
    person
};

#END#

i:(::person)=
{
    person=NewPerson(),
    person.BCM("姓名").FCDstrcpy("王强",false),
    person.BCM("性别").FCDstrcpy("男",false),
    person.BCM("年龄").set(22)
};

i:(::person)= person.BCM("姓名").OutStr[];
i:(::person)= person.BCM("性别").OutStr[];
i:(::person)= person.BCM("年龄").get();
i:(::person)= person.BCM("省份").OutStr[];

i:(::person,p)=
{
    p=NewPerson(),
    copy(p,person)
};
i:(::person)= person.BCM("姓名").FCDstrcpy("李平",false);
i:(::person)= person.BCM("省份").FCDstrcpy("北京市",false);

i:(::person)= person.BCM("姓名").OutStr[];
i:(::person)= person.BCM("性别").OutStr[];
i:(::person)= person.BCM("年龄").get();
i:(::person)= person.BCM("省份").OutStr[];
i:(::person)= delete(person);

i:(::p)= p.BCM("姓名").OutStr[];
i:(::p)= p.BCM("性别").OutStr[];
i:(::p)= p.BCM("年龄").get();
i:(::p)= p.BCM("省份").OutStr[];
i:(::p)= delete(p);

6 类成员函数

    FcData中定义的类没有成员函数的概念。但如果一个模块输出了一个类,则可以使用模块命名空间中的函数作为类的成员函数。如下例:

#MODULE#                                      //定义模块Int2Op,对两个整数进行运算

      !Module("Int2Op");                      //创建模块命名空间Int2Op

i::NewCInt2Op(:static,_CInt2Op,free:CInt2Op)=    //定义类CInt2Op,该函数不会自动执行
{
    if[free,delete(_CInt2Op),return(0)],
 //销毁表达式时,自动销毁申请的对象
    CInt2Op=new(cdef:"x","y"),_CInt2Op=CInt2Op
};

i:InitInt2Op(:x,static,nFree)=          //初始化模块Int2Op,nFree用于标记类定义CPerson是否被函数DeleteAllFCD()销毁
{
    if{!static,static=1,nFree=nDeleteAllFCD(),NewCInt2Op(),return(0)},
    x=nDeleteAllFCD(),
    if{nFree!=x,nFree=x,NewCInt2Op()}
};

~i::NewInt2Op(:Int2Op:CInt2Op)=         //申请类Int2Op的对象,该函数不会自动执行,全局函数
{
    InitInt2Op(),
                       //如果类定义CInt2Op已被函数DeleteAllFCD()销毁重新NewCInt2Op()
    Int2Op=new(class,CInt2Op),
    Int2Op."x".SetCM[new(int),true],
    Int2Op."y".SetCM[new(int),true],
    Int2Op
};

i:add(p)=                               //计算对象Int2Op的两个成员"x"和"y"的和
{
    p.BCM("x").get()+p.BCM("y").get()
};

i:sub(p)=                               //计算对象Int2Op的两个成员"x"和"y"的差
{
    p.BCM("x").get()-p.BCM("y").get()
};

!OutFun("add","sub");                   //输出模块命名空间中的表达式

#END#

i: (::a)= a=NewInt2Op(), a.BCM("x").set(2), a.BCM("y").set(5);  //主模块中的表达式
i: (::a)= a.Int2Op::add();                    //主模块中的表达式
i: (::a)= a.Int2Op::sub();                    //主模块中的表达式
i: (::a)= delete(a);

7 虚函数与多态性 [返回页首]

    Forcal是动态编译运行的,多态性是Forcal是一个基本特征。通过虚函数实现运行时的多态性给程序提供了更大的灵活性。

7.1 整数运算的例子

#MODULE#                                     //定义模块Int2Op,对两个整数进行运算

      !Module("Int2Op");                     //创建模块命名空间Int2Op

i::NewCInt2Op(:static,_CInt2Op,free:CInt2Op)=    //定义类CInt2Op,该函数不会自动执行
{
    if[free,delete(_CInt2Op),return(0)],
 //销毁表达式时,自动销毁申请的对象
    CInt2Op=new(cdef:"x","y"),_CInt2Op=CInt2Op
};

i:InitInt2Op(:x,static,nFree)=          //初始化模块Int2Op,nFree用于标记类定义CPerson是否被函数DeleteAllFCD()销毁
{
    if{!static,static=1,nFree=nDeleteAllFCD(),NewCInt2Op(),return(0)},
    x=nDeleteAllFCD(),
    if{nFree!=x,nFree=x,NewCInt2Op()}
};

~i::NewInt2Op(:Int2Op:CInt2Op)=         //申请类Int2Op的对象,该函数不会自动执行,全局函数
{
    InitInt2Op(),
                       //如果类定义CInt2Op已被函数DeleteAllFCD()销毁重新NewCInt2Op()
    Int2Op=new(class,CInt2Op),
    Int2Op."x".SetCM[new(int),true],
    Int2Op."y".SetCM[new(int),true],
    Int2Op
};

i:add(p)=                               //计算对象Int2Op的两个成员"x"和"y"的和
{
    p.BCM("x").get()+p.BCM("y").get()
};

i:sub(p)=                               //计算对象Int2Op的两个成员"x"和"y"的差
{
    p.BCM("x").get()-p.BCM("y").get()
};

!OutFun("add","sub");                   //输出模块命名空间中的表达式

#END#

#MODULE#                                     //定义模块Int3Op,继承自Int2Op,对三个整数进行运算,其中两个整数来自基类Int2Op

      !Module("Int3Op","Int2Op");            //创建模块命名空间Int2Op,继承自Int2Op

i::NewCInt3Op(:static,_CInt3Op,free:CInt3Op)=    //定义类CInt3Op,该函数不会自动执行
{
    if[free,delete(_CInt3Op),return(0)],
 //销毁表达式时,自动销毁申请的对象
    CInt3Op=new(cdef:"Int2Op","z"),_CInt3Op=CInt3Op
};

i:InitInt3Op(:x,static,nFree)=          //初始化模块Int3Op,nFree用于标记类定义CPerson是否被函数DeleteAllFCD()销毁
{
    if{!static,static=1,nFree=nDeleteAllFCD(),NewCInt3Op(),return(0)},
    x=nDeleteAllFCD(),
    if{nFree!=x,nFree=x,NewCInt3Op()}
};

~i::NewInt3Op(:Int3Op:CInt3Op,add,sub)= //申请类Int3Op的对象,该函数不会自动执行,全局函数
{
    InitInt3Op(),
                       //如果类定义CInt3Op已被函数DeleteAllFCD()销毁重新NewCInt3Op()
    Int3Op=new(class,CInt3Op),
    Int3Op."Int2Op".SetCM[NewInt2Op(),true],
    Int3Op."z".SetCM[new(int),true],
    Int3Op
};

i:add(p)=                               //计算对象Int3Op的三个成员"x"、"y"和"z"的和,其中"x"和"y"来自基类Int2Op
{
    p.BCM("x").get()+p.BCM("y").get()+p.BCM("z").get()
};

i:sub(p)=                               //计算对象Int3Op的三个成员"x"、"y"和"z"的差,其中"x"和"y"来自基类Int2Op
{
    p.BCM("x").get()-p.BCM("y").get()-p.BCM("z").get()
};

!OutFun("add","sub");                   //输出模块命名空间中的表达式

#END#

i: (::a)= a=NewInt3Op(), a.BCM("x").set(2), a.BCM("y").set(5), a.BCM("z").set(8);  //主模块中的表达式
i: (::a)= a.Int3Op::add();                    //主模块中的表达式 ,调用派生类的成员函数add
i: (::a)= a.Int3Op::sub();                    //主模块中的表达式 ,调用派生类的成员函数
sub
i: (::a)= a.Int3Op::Int2Op::add()           //主模块中的表达式 ,调用基类的成员函数
add
i: (::a)= a.Int3Op::Int2Op::sub();            //主模块中的表达式 ,调用基类的成员函数
sub
i: (::a)= delete(a);

7.2 几何图形面积的例子

    在这个例子中,创建了一个基类Area,它是一个几何图形的二维面积。同时还创建了一个虚函数GetArea(),当派生类覆盖GetArea()时,GetArea()返回派生类定义的几何形状的面积。该程序计算了一个矩形的面积。为了简单,该程序使用整数进行计算。

#MODULE#   //类模块Area,有两个数据成员"dim1"和"dim2",三个函数成员SetArea、GetDim和GetArea,其中GetArea为虚函数,在派生类中要覆盖该函数

      !Module("Area");                              //创建模块命名空间Area

i::NewCArea( : static,_CArea,free : CArea)=   //定义类CArea,该函数不会自动执行
{
    if[free,delete(_CArea),return(0)],
        //销毁表达式时,自动销毁申请的对象
    CArea=new(cdef:"dim1","dim2"
),_CArea=CArea
};

i:InitArea(:x,static,nFree)=                  //初始化模块Area,nFree用于标记类定义CArea是否被函数DeleteAllFCD()销毁
{
    if{!static,static=1,nFree=nDeleteAllFCD(),NewCArea(),return(0)},
    x=nDeleteAllFCD(),
    if{nFree!=x,nFree=x,NewCArea()}
};

~i::NewArea(::CArea)=                         //申请类Area的对象,该函数不会自动执行,全局函数
{
    InitArea(),
                               //如果类定义CArea已被函数DeleteAllFCD()销毁重新NewCArea()
    new{class,CArea,
        "dim1",new(int),
        "dim2",new(int)
    }
};

i:SetArea(p,d1,d2)=                           //设置对象Area的两个成员"dim1"和"dim2"的值
{
    p.BCM("dim1").set(d1), p.BCM("dim2").set(d2)
};

i:GetDim(p,d1,d2)=                            //得到对象Area的两个成员"dim1"和"dim2"的值
{
    p.BCM("dim1").get(&d1), p.BCM("dim2").get(&d2)
};

i:GetArea(p)=                                 //得到对象Area表示的图形面积,虚函数,派生类要覆盖该函数
{
    MessageBox("这是个虚函数,派生类必须覆盖该函数!","Area")
};

!OutFun("SetArea","GetDim","GetArea");        //输出模块命名空间中的表达式

#END#

#MODULE#   //类模块Rectangle,继承自Area,覆盖了基类的成员函数GetArea

      !Module("Rectangle":"Area");            //创建模块命名空间Rectangle,继承自Area

i::NewCRectangle( : static,_CRectangle,free : CRectangle)= //定义类CRectangle,该函数不会自动执行
{
    if[free,delete(_CRectangle),return(0)],
 //销毁表达式时,自动销毁申请的对象
    CRectangle=new(cdef:"
Area"),_CRectangle=CRectangle
};

i:InitRectangle(:x,static,nFree)=        //初始化模块Rectangle,nFree用于标记类定义CRectangle是否被函数DeleteAllFCD()销毁
{
    if{!static,static=1,nFree=nDeleteAllFCD(),NewCRectangle(),return(0)},
    x=nDeleteAllFCD(),
    if{nFree!=x,nFree=x,NewCRectangle()}
};

~i::NewRectangle(::CRectangle,GetArea)=  //申请类Rectangle的对象,该函数不会自动执行,全局函数
{
    InitRectangle(),
                     //如果类定义CRectangle已被函数DeleteAllFCD()销毁重新NewCRectangle()
    new{class,CRectangle,
        "
Area",NewArea()
    }
};

i:GetArea(p:d1,d2)=                      //得到对象Area表示的矩形的面积,覆盖了基类的同名函数
{
    p.
Area::GetDim(&d1,&d2),             //调用基类的成员函数GetDim,获得图形尺寸
    d1*d2
};

!OutFun("GetArea");                      //输出模块命名空间中的表达式

#END#

i: (::a)= a=NewRectangle(), a.Rectangle::SetArea(2,3);  //主模块中的表达式,调用基类的成员函数SetArea
i: (::a)= a.Rectangle::GetArea();                       //主模块中的表达式,调用派生类的成员函数GetArea
i: (::a)= a.Rectangle::Area::GetArea();                 //主模块中的表达式,调用基类的成员函数
GetArea
i: (::a)= delete(a);


版权所有© Forcal数学软件 2002-2009,保留所有权利
E-mail:
forcal@sina.com
  QQ:630715621
最近更新: 2009年06月10日