JCOOP入门指南[02]
上一篇中用JCOOP[sourceforge.net/projects/jcoop]设计了一个最最简单的Baby类,但是如果都像这样做的话一旦类的规模增大,
每声明一个实例,有些时候就要额外的占用一定的空间[比如类方法使用的指针],
为了节约资源,在JCOOP中一个类其实包含了两部分,一部分存储每个实例的属性成员,
另一部分存储公共的变量,可以是共享变量也可以是公用的方法[这类似与C++中的虚表]
而其声明方式类似下面这样,
CLASS(A)
......//普通成员
SHARE(A)
......//方法或共享成员
END_CLASS
而每个类的私有部分和公有部分通过一个名为share的指针(如果声明了公有部分则存在于私有部分,否则不存在)
指向公有部分.
类似的,类的构造和析构也有相应的宏CTOR...CTORS...END_CTOR和DTOR...DTORS...END_DTOR来声明.
具体见下面的代码,
#include <stdio.h> #include "./include/jc_oop.h" CLASS(Baby) unsigned int age; //表示年龄的成员 SHARE(Baby) METHOD(unsigned int,getAge)(void *); METHOD(void,setAge)(void *,unsigned int); METHOD(void,cry)(void *); //两个void分别对应返回值和参数 END_CLASS static void Jcry(void *z){ printf("baby is crying...\n"); } static unsigned int JgetAge(void *z){ ZS(Baby); return this->age; } static void JsetAge(void *z,unsigned int age){ ZS(Baby); this->age=age; } CTOR(Baby) //构造函式 printf("Baby constructor called ... \n"); ASSIGN(age,1); //赋值 CTORS(Baby) printf("Baby share part constructor called ... \n"); CONNECT(cry,Jcry); //链接到指定的函式 CONNECT(getAge,JgetAge); CONNECT(setAge,JsetAge); END_CTOR DTOR(Baby) //析构函式 printf("Baby destructor called ... \n"); UNASSIGN(age); //置零 DTORS(Baby) printf("Baby share part destructor called ... \n"); DISCONNECT(getAge); DISCONNECT(setAge); DISCONNECT(cry); //断开链接 END_DTOR int main(){ NEW_BUNDLE(Baby,baby,bs); printf("the baby's age is %d\n",bs->getAge(baby)); bs->cry(baby); bs->setAge(baby,3); printf("the baby's age is %d\n",bs->getAge(baby)); DEL(Baby,baby); DELS(Baby,bs); return 0; }
这里要特别声明的是如果用ZS宏,第一个参数的声明应为void *z,这样才会正确的转换成相应的"this指针"
编译正确后,会输出如下,
Baby share part constructor called ... Baby constructor called ... the baby's age is 1 baby is crying... the baby's age is 3 Baby destructor called ... Baby share part destructor called ...
另外顺带要说一下NEW_BUNDLE这个宏,其相当于NEWS和NEW这两个宏的组合,第一次声明某个实例时使用该宏会更加简洁.
和前面讲到的CTORS和DTORS一样,那个末尾的S表示SHARE,也就是公有部分.
而程序中我们实际使用的是两个类型分别BabyShare和Baby指针,其分别指向了两个在堆上创建的实例.
当然如果你正确的使用NEW和DEL等宏,那么一般不用过多关注堆上类所用内存的分配.