JCOOP入门指南[02]
JCOOP入门指南[04]

JCOOP入门指南[03]

pingf posted @ Fri, 09 Jul 2010 07:35:21 -1100 in C语言 with tags 创作 , 3484 readers

通过前面的介绍,相信本文的读者(具备一定编程基础)对JCOOP[sourceforge.net/projects/jcoop]有了大致的了解

本节依旧是以实例为主来说明如何使用JCOOP来模拟"继承"这一OO中重要的元素.

 

C语言中本没有类的概念,但其实有了结构体和函数指针,一个类的最基本功能是都可以实现的.前文中这些都已介绍了.

不过学过CPP和JAVA都知道,OO中必然有继承,这是C语言中所没有的,那么如何用C来实现呢?

准确说来C只能说是来模拟,而不能实现所有继承的功能,而模拟的方法自然还是用结构体[C中就那么点东西啊....]

具体见下面的示例

struct A{

        int a;

};

struct B{

        struct  A   stA;

        int b;

};

后面的结构体b包含了a结构体的一个实例.而类型转换时遵循位置靠前的原则.

在JCOOP中定义了如下一些宏来方便的实现继承这一功能,

类的声明中使用-->EXTD(共享部分使用EXTDS)

类的构造中使用-->SU_CTOR(共享部分使用SU_CTORS)

类的析构中使用-->SU_DTOR(共享部分使用SU_DTORS)

具体可以看下面的代码[如果感觉下面的代码仍有些怪异,请阅读前面相关JCOOP的文章]

 

#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分别对应返回值和参数
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 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(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


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)); 


	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;
}

运行时,会显示下面的字符,

Baby share part constructor called ... 
Boy share part 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

***** now test the conversion *****

baby is crying...
the baby's age is 15
Boy destructor called ... 
Baby destructor called ... 
Boy share part destructor called ... 
Baby share part destructor called ... 

上面这个实例实现了一个Boy类,该类继承了前面的Baby类[见前文],

这里仅简单说明以下几点,

    1.Boy中继承了Baby类,共享部分也是如此.

    2.Boy中类也实现了单独的cry方法,你可以将这种方式理解成函数的重写.

    3.类型转换时,因为上面程序中都是使用CAST_PTR宏,因为类都建立在堆上,我们只是用指向其的指针.

    4.如果最后调用babys->cry();那么还是打印baby is crying ......

    5.注意上面constructor和destructor调用的辅助文字仅仅在说明调用的次序,当然如果你改变它的位置,打印的位置也会有所改变.

    6.另外JboyCry()仅仅是因为两个类都放在一个文件中,为了避免重名才这样做.

 

 

 


Login *


loading captcha image...
(type the code from the image)
or Ctrl+Enter