以下のメッセージを削除します。


[2028] 『Java 謎』3.3 寄り道 - Cで継承を実現してみる
返信


投稿者:藤四郎
2017/11/29 00:44:18

Link:
『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;
}

---------------------------------------------------------

パスワード:

管理者削除