JCOOP入门指南[03]
C语言模拟OO机制的再研究

JCOOP入门指南[04]

pingf posted @ Sun, 18 Jul 2010 06:32:18 -1100 in C语言 with tags 创作 , 2404 readers

//修改 : 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 ... 
KVS Question Paper said:
Wed, 21 Sep 2022 07:41:30 -1100

KVS Sample Paper 2023 Pdf Download for Kendriya Vidyalaya Sangathan Class 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 & 12 Arts, KVS Question Paper Science & Commerce Stream Practice Paper Suggestions with Past years old exam Solved Question Bank for all Regional Students of English Medium, Hindi Medium & Urdu Medium Studying in KVS Schools across the Country. All the Kendriya Vidyalaya Sangathan Board Students can download the Sample Paper Suggestions with Model Papers along with Previous Years old Exam Solved Question Bank for all Languages & Subjects of the Course.

civaget said:
Wed, 13 Dec 2023 09:05:18 -1100

SEO enthusiasts, take note: 백링크 is the secret sauce. Quality over quantity is the rule of thumb here. Learn the ropes of acquiring high-value backlinks to propel your website to new heights.

civaget said:
Sat, 16 Dec 2023 02:24:49 -1100

The convenience of 수원출장마사지 is a game-changer for busy folks like me. Thanks for sharing!

civaget said:
Tue, 19 Dec 2023 04:12:56 -1100

The reliability of 축구중계 is unmatched. Lag-free streams, always!

civaget said:
Wed, 20 Dec 2023 09:03:59 -1100

I can't stop praising 동대문휴게텔. It's the epitome of relaxation, and the diverse massage options ensure every visitor's needs are met.

civaget said:
Thu, 21 Dec 2023 09:39:46 -1100

토토매치's commitment to safety is commendable. Enjoy worry-free betting with their transparent operations and impressive 100 times compensation guarantee.

civaget said:
Fri, 29 Dec 2023 22:37:33 -1100

The benefits of 휴식 are evident, and OPGuide's comprehensive approach is impressive.

civaget said:
Wed, 10 Jan 2024 01:59:55 -1100

오피가이드 is a must-visit for anyone seeking relaxation in KOREA.


Login *


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