OOPC-クラス実装マルチインタフェース(multiple interface)


1つのクラスは複数のインタフェースを実現して、このプログラムは自分の方法で実現して、しかし最後に主な関数のあれはあまりはっきり見ていないで、もし通りかかった大神があるならば、面倒なことを見てあなたの高見を残して、下のコードは2つのインタフェースを通じてそれぞれ1つのオブジェクト(矩形)の面積と周長を計算して、具体的なコードは以下の通りです:1、面積のインタフェースを計算します
#ifndef __C14IB_H__
#define __C14IB_H__

typedef struct
{
     
	void (*init)(void*, double, double);
	double (*cal_area)(void*);
}IB_t;

#endif

2、周長インタフェースの計算
#ifndef __C14IC_H__
#define __C14IC_H__


typedef struct
{
     
	void (*init)(void*, double ,double);
	double (*cal_perimeter)(void*);
}IC_t;

#endif

3、以下は1つのクラスを定義して、同時に上述の2つのインタフェースを支持して、しかも互いに変換することができて、具体的にどのように変換して、これは私の問題で、よく見ていないで、コードは以下の通りです:
#ifndef __C14ALL_H__
#define __C14ALL_H__

#include "c14ic.h"
#include "c14ib.h"

typedef struct
{
     
	IB_t Ib;
	IC_t Ic;
	
}IALL_t;

#endif

4.次に矩形のクラスを定義し、具体的なオブジェクトを抽象化する
#ifndef __C14REC_H__
#define __C14REC_H__
#include "c14all.h"

typedef struct
{
     
	IC_t Ic;
	IB_t Ib;

	double lenth;
	double width;
	void (*display)(char*,double);
	
}REC_t;

void *RecNew(void);

#endif

5、クラスを実現する方法
#include 
#include 
#include "c14rec.h"

static void init(void *t, double length, double width)
{
     
	REC_t *cthis = (REC_t*)t;
	
	cthis->lenth = length;
	cthis->width = width;
}
static double calculate_area(void *t)
{
     
	REC_t *cthis = (REC_t*)t;
	double s;

	s = (cthis->lenth) * (cthis->width);
	cthis->display("area ",s);

	return s;
}

static double calculate_perimeter(void *t)
{
     
	REC_t *cthis = (REC_t *)t;
	double p;

	p = ((cthis->lenth) + (cthis->width)) * 2;
	cthis->display("perimeter",p);

	return p;
}

static void display(char *str, double d)
{
     
	printf("%s=%7.2f
"
,str,d); } void *RecNew(void) { REC_t *t; t= (REC_t*)malloc(sizeof(REC_t)); t->display = display; t->Ib.init = init; t->Ib.cal_area = calculate_area; t->Ic.init = init; t->Ic.cal_perimeter = calculate_perimeter; return (void*)t; }

6、主関数
#include 
#include "c14all.h"
#include "c14rec.h"

int main()
{
     
	IB_t *pb;
	IC_t *pc;
	IALL_t *pa;
	double a;

	pb = (IB_t *)RecNew();
	
	pb->init(pb, 20.0,10.0);
	a = pb->cal_area(pb);

	pa = (IALL_t*)pb;
	pc = &(pa->Ic);
	a= pc->cal_perimeter(pa);
	
	
	return 0;
}


主関数では、pbが矩形オブジェクトの面積インタフェースIB_を指しているt;オブジェクトを初期化し、オブジェクトの面積を計算します.pbは2つの共通インタフェースを指すpaに伝達され、paからIC_に伝達される.tのpc値は、最後にpcを直接呼び出して周長を計算する.ここは変換がとてもきれいなようで、しかし人をぼんやりさせやすくて、私は更にちょうどデバッグの過程の中で間違いを始めて、例えばa=pc->cal_perimeter(pa);paに伝わると間違って伝わります.だから誰が通りかかった大神が迷津を教えてくれることを望んでいます!