K.Maebashi's BBS

ご自由に書き込んでください。雑談も可。
テスト書き込みの類はテスト用掲示板にどうぞ

[日付順表示] [日付順インデックス] [スレッド順インデックス]

新規投稿 | 開設者ホームページへ戻る | ヘルプ

[2028] 『Java 謎』3.3 寄り道 - Cで継承を実現してみる
投稿者:藤四郎
2017/11/29 00:44:18

『Java 謎+落とし穴 徹底解明』 3.3 寄り道 - Cで継承を実現してみる p.177 - List 3.11 - 3.22 について、 たとえば ExtendedPolyline を追加す るとしたらどうするのか、つたないながら考えてみました。 ここのところいろいろご面倒をおかけしておりますが、またよろしければご叱 正いただけると幸いです。 (なお、 http://kmaebashi.com/programmer/c_yota/inherit.html も拝見しましたが、申し訳ないことにいまのわたしには難解でした。) まず、 Shape.c の MethodTableIndex を Shape.h に移動するのはまずいでしょ うか。しかし、そうしたとして、あとは以下のファイルを改変または追加しました。 (なお、 Shape は abstract 相当と理解しております。) ---- Polyline.h ----------------------------------------- #ifndef POLYLINE_H_INCLUDED #define POLYLINE_H_INCLUDED #include "Shape.h" #include "Point2D.h" typedef struct { Shape super; int nPoints; Point2D *point; } Polyline; Polyline *createPolyline(void); void drawPolyline(Polyline *polyline); ClassDescriptor *getPolylineClassDescriptor(void); #endif /* POLYLINE_H_INCLUDED */ ---- Polyline.c ----------------------------------------- #include <stdio.h> #include <stdlib.h> #include "Polyline.h" static void drawPolylineImpl(void); static void (*methodTable[])() = { drawPolylineImpl }; static ClassDescriptor polylineClassDescriptor = { methodTable }; ClassDescriptor *getPolylineClassDescriptor(void) { return &polylineClassDescriptor; } Polyline *createPolyline(void) { Polyline *p = malloc(sizeof(Polyline)); p->super.super.classDescriptor = &polylineClassDescriptor; p->nPoints = 0; p->point = NULL; return p; } void drawPolyline(Polyline *polyline) { polyline->super.super.classDescriptor->methodTable[(int)DRAW_INDEX](); } static void drawPolylineImpl(void) { fprintf(stderr, "Polylineを描画\n"); } ---- ExtendedPolyline.h --------------------------------- #ifndef EXTENDED_POLYLINE_H_INCLUDED #define EXTENDED_POLYLINE_H_INCLUDED #include "Polyline.h" #include "Point2D.h" typedef struct { Polyline super; int nPoints; Point2D *point; } ExtendedPolyline; ExtendedPolyline *createExtendedPolyline(void); void drawExtendedPolyline(ExtendedPolyline *extendedPolyline); #endif /* EXTENDED_POLYLINE_H_INCLUDED */ ---- ExtendedPolyline.c --------------------------------- #include <stdio.h> #include <stdlib.h> #include <memory.h> #include "ExtendedPolyline.h" static void drawExtendedPolylineImpl(void); static void (*methodTable[])() = {}; static ClassDescriptor extendedPolylineClassDescriptor = { methodTable }; /* このへんがとりわけリアリティにかけるのかも…… */ void initExtendedPolyline(void) { ClassDescriptor *cd = getPolylineClassDescriptor(); void (**mt)() = cd->methodTable; memcpy(methodTable, mt, sizeof(mt)); methodTable[(int)DRAW_INDEX] = drawExtendedPolylineImpl; } ExtendedPolyline *createExtendedPolyline(void) { ExtendedPolyline *ep = malloc(sizeof(ExtendedPolyline)); /* http://kmaebashi.com/programmer/c_yota/inherit.html には super.super.super.... を回避する裏技が紹介されていますが…… */ ep->super.super.super.classDescriptor = &extendedPolylineClassDescriptor; ep->nPoints = 0; ep->point = NULL; return ep; } void drawExtendedPolyline(ExtendedPolyline *extendedPolyline) { extendedPolyline->super.super.super.classDescriptor->methodTable[(int)DRAW_INDEX](); } static void drawExtendedPolylineImpl(void) { fprintf(stderr, "ExtendedPolylineを描画\n"); } ---- draw.h --------------------------------------------- #include "Shape.h" void draw(Shape **shapes); ---- draw.c --------------------------------------------- /* http://kmaebashi.com/bbs/thread.php?boardid=kmaebashibbs&from=1906&range=1 */ #include <stdio.h> #include "Shape.h" void draw(Shape **shapes) { int i; for (i = 0; i < 4; i++) { drawShape(shapes[i]); } } ---- main.c --------------------------------------------- #include <stdio.h> #include "Shape.h" #include "Polyline.h" #include "Circle.h" #include "Rectangle.h" #include "ExtendedPolyline.h" #include "draw.h" int main(void) { Shape *shapes[4]; int i; initExtendedPolyline(); shapes[0] = (Shape*)createPolyline(); shapes[1] = (Shape*)createCircle(); shapes[2] = (Shape*)createRectangle(); shapes[3] = (Shape*)createExtendedPolyline(); draw(shapes); printf("\n"); drawPolyline(createPolyline()); drawPolyline((Polyline*)createExtendedPolyline()); drawExtendedPolyline(createExtendedPolyline()); return 0; } ---------------------------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]