//修改 : 2010.7.25 修正自JCOOP 0.12之后[不包括0.12]SUB_CTOR宏接受三个参数,最后一个参数显示的指明共享部分的指针名称
//这两天对JCOOP核心的宏做了一些修改[本文编写时这个版本还未上传,不过也快了],主要是增加了些返回的状态,
//便于出错后的检测,不过因为用到的printf,所以某些超低端嵌入式平台如果使用最好做一些修改,以减小代码体积.
继前文介绍了JCOOP[sourceforge.net/projects/jcoop]类的设计方法[简化类,标准类,以及含有继承的类],
本篇介绍使用JCOOP中的"包含"
假设某个机车的核心是一个发动机,
我们可以这样设计这些类,
先设计一个发动机类,再从此类派生一个汽车类.
但也可采用下面的方法,
设计一个汽车类,在此类中包含一个指向原先设计好的发动机类的指针.
上面的例子中显然后者更和常理,绝大多数情况下,两种设计可以互相转化.
在良好的设计中应该尽可能的使用第二种设计方式,尽管这样会舍弃了一些语言本身的简易特性,但会使得代码更易修改,耦合度低,程序更加紧凑.....
下面的叙述还是采用上一篇中的代码,稍作修改,以演示如何在JCOOP中方便的使用"包含"的方式去设计一个类
先设计一个非常简单的Toy类
CLASS(Toy)
unsigned char *name;
SHARE(Toy)
METHOD(void,playWithToy)(void *);
END_CLASS
然后我们假设每个小孩都有一个玩具,并且可以玩!
这样Baby类就变成了下面这样
CLASS(Baby)
HAVE(Toy,toy);
unsigned int age; //表示年龄的成员
SHARE(Baby)
HAVES(Toy,toy);
METHOD(unsigned int,getAge)(void *);
METHOD(void,setAge)(void *,unsigned int);
METHOD(void,cry)(); //两个void分别对应返回值和参数
END_CLASS
而Baby的构造函数就变成了
CTOR(Baby) //构造函式
SUB_CTOR(Toy,toy); //注意,0.12后的版本应使用SUB_CTOR(Toy,toy,toy),这样可以指定对应共享部分指针的名称
printf("Baby constructor called ... \n");
ASSIGN(age,1); //赋值
CTORS(Baby)
SUB_CTORS(Toy,toy);
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); //置零
SUB_DTOR(Toy,toy);
DTORS(Baby)
printf("Baby share part destructor called ... \n");
DISCONNECT(getAge);
DISCONNECT(setAge);
DISCONNECT(cry); //断开链接
SUB_DTORS(Toy,toy);
END_DTOR
注意到
在CLASS中使用的是HAVE...HAVES的组合[要注意,共享和非共享部分的指针名称应保证一致,否则会报错]
在CTOR中使用的是SUB_CTOR...SUB_CTORS的组合
在DTOR中使用的是SUB_DTOR...SUB_DTORS的组合
下面列出完整的代码
#include <stdio.h>
#include "jc_oop.h"
CLASS(Toy)
unsigned char *name;
SHARE(Toy)
METHOD(void,playWithToy)(void *);
END_CLASS
CLASS(Baby)
HAVE(Toy,toy);
unsigned int age; //表示年龄的成员
SHARE(Baby)
HAVES(Toy,toy);
METHOD(unsigned int,getAge)(void *);
METHOD(void,setAge)(void *,unsigned int);
METHOD(void,cry)(); //两个void分别对应返回值和参数
END_CLASS
CLASS(Boy)
EXTD(Baby);
unsigned int sex;
unsigned char * favor;
SHARE(Boy)
EXTDS(Baby);
METHOD(int,setFavor)(void *,const unsigned char *);
METHOD(unsigned char *,getFavor)(void *);
METHOD(void,cry)();
END_CLASS
static void JplayWithToy(void *z){
ZS(Toy);
printf("\n>>>>> \n");
printf("playing with %s\n",this->name);
printf(" <<<<<\n\n");
}
static void Jcry(){
printf("baby is crying...\n");
}
static void JboyCry(){
printf("boy 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;
}
static int JsetFavor(void *z,const unsigned char *str){
ZS(Boy);
unsigned int len=strlen(str)+1;
if((this->favor=(unsigned char *)malloc(sizeof(unsigned char)*len))!=NULL){
strncpy(this->favor,str,len);
return 1;
}
return 0;
}
static unsigned char * JgetFavor(void *z){
ZS(Boy);
return this->favor;
}
CTOR(Toy) //构造函式
printf("Toy constructor called ... \n");
ASSIGN(name,"audi car mini-model"); //赋值
CTORS(Toy)
printf("Toy share constructor called ... \n");
CONNECT(playWithToy,JplayWithToy);
END_CTOR
DTOR(Toy) //构造函式
printf("Toy destructor called ... \n");
UNASSIGN(name);
DTORS(Toy)
printf("Toy share destructor called ... \n");
DISCONNECT(playWithToy);
END_DTOR
CTOR(Baby) //构造函式
SUB_CTOR(Toy,toy); //注意,0.12后的版本应使用SUB_CTOR(Toy,toy,toy),这样可以指定对应共享部分指针的名称
printf("Baby constructor called ... \n");
ASSIGN(age,1); //赋值
CTORS(Baby)
SUB_CTORS(Toy,toy);
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); //置零
SUB_DTOR(Toy,toy);
DTORS(Baby)
printf("Baby share part destructor called ... \n");
DISCONNECT(getAge);
DISCONNECT(setAge);
DISCONNECT(cry); //断开链接
SUB_DTORS(Toy,toy);
END_DTOR
CTOR(Boy)
SU_CTOR(Baby);
printf("Boy constructor called ... \n");
ASSIGN(Baby.age,10);
ASSIGN(sex,1);
unsigned int len=strlen("play football")+1;
this->favor=(unsigned char *)malloc(sizeof(unsigned char)*len);
strncpy(this->favor,"play football\0",len);
CTORS(Boy)
SU_CTORS(Baby);
printf("Boy share part constructor called ... \n");
CONNECT(cry,JboyCry); //链接到指定的函式
CONNECT(getFavor,JgetFavor);
CONNECT(setFavor,JsetFavor);
END_CTOR
DTOR(Boy)
printf("Boy destructor called ... \n");
UNASSIGN(sex);
free(this->favor);
this->favor=NULL;
SU_DTOR(Baby);
DTORS(Boy)
printf("Boy share part destructor called ... \n");
DISCONNECT(cry); //断开链接
DISCONNECT(getFavor);
DISCONNECT(setFavor);
SU_DTORS(Baby);
END_CTOR
int main(){
NEW_BUNDLE(Boy,boy,bs);
printf("the boy's age is %d\n",bs->Baby.getAge(boy));
bs->Baby.setAge(boy,15);
printf("the boy's age is %d\n",bs->Baby.getAge(boy));
bs->cry();
printf("the boy's favor is %s\n",bs->getFavor(boy));
bs->setFavor(boy,"play basketball");
printf("the boy's favor is %s\n",bs->getFavor(boy));
bs->Baby.toy->playWithToy(boy->Baby.toy);
printf("\n***** now test the conversion *****\n\n");
BabyShare *babys=NULL;
babys=CAST_PTR(BabyShare,bs);
babys->cry();
Baby *baby=NULL;
baby=CAST_PTR(Baby,boy);
printf("the baby's age is %d\n",babys->getAge(baby));
DEL(Boy,boy);
DELS(Boy,bs);
return 0;
}
正确的运行结果如下,
Toy share constructor called ...
Baby share part constructor called ...
Boy share part constructor called ...
Toy constructor called ...
Baby constructor called ...
Boy constructor called ...
the boy's age is 10
the boy's age is 15
boy is crying...
the boy's favor is play football
the boy's favor is play basketball
>>>>>
playing with audi car mini-model
<<<<<
***** now test the conversion *****
baby is crying...
the baby's age is 15
Boy destructor called ...
Baby destructor called ...
Toy destructor called ...
Boy share part destructor called ...
Baby share part destructor called ...
Toy share destructor called ...