ポリモーフィズムの利用
CoddyのCジャーニー「Object Oriented Programming」セクションの一部 — レッスン 47/61。
チャレンジ
簡単CircleであれRectangleであれ、ベースとなる Shape* ポインタを介してあらゆる図形を処理できる関数を記述することで、ポリモーフィズムが真に機能することを証明しましょう。
既存のCircleとRectangleの実装を基に、強力な抽象化を追加します。それは、あらゆる図形タイプを一律に扱う単一の関数です。
プロジェクトには以下のファイルが含まれます:
shape.h:DrawFunc型とAreaFunc型を持つベースのShapeインターフェース。circle.hおよびcircle.c: 前のレッスンで作成したCircleの実装。rectangle.hおよびrectangle.c: 前のレッスンで作成したRectangleの実装。shape.c:Shape*ポインタを受け取るprocess_shapeという新しい関数を実装します。この関数は、図形のdraw関数を呼び出し、次にそのarea関数を呼び出して、結果を小数点以下2桁のArea: X.XXという形式で出力する必要があります。main.c: ポリモーフィズムの動作を実演します。図形タイプのインジケータ(circleの場合はc、rectangleの場合はr)と、それに続く必要な寸法を読み取ります。適切な図形を作成し、その埋め込まれたShapeメンバへのポインタをprocess_shapeに渡します。同じ関数が両方のタイプを処理します!
プログラムは以下のいずれかを受け取ります:
cとそれに続く半径の値、またはrとそれに続く幅と高さの値
入力が c と 5.0 の場合の出力例:
Drawing Circle with radius: 5.00
Area: 78.54入力が r、4.0、および 3.0 の場合の出力例:
Drawing Rectangle with width: 4.00 and height: 3.00
Area: 12.00ここでの魔法は、process_shape がCircleを扱っているのかRectangleを扱っているのかを全く知らないということです。それは Shape インターフェースのことしか知りません。具体的な図形の埋め込み Shape メンバを Shape* にキャストすることで、この単一の関数にあらゆる図形タイプを渡すことができます。これがポリモーフィズムです。1つの関数が、実際のオブジェクトの型に基づいて複数の振る舞いを見せます。
main.c から呼び出せるように、shape.h で process_shape を宣言することを忘れないでください。
自分で試してみよう
#include <stdio.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
int main() {
// TODO: 図形の種類の文字('c' は circle、'r' は rectangle)を読み込む
// TODO: 'c' の場合、半径を読み込み、Circle を作成し、その base を指定して process_shape を呼び出す
// TODO: 'r' の場合、幅と高さを読み込み、Rectangle を作成し、その base を指定して process_shape を呼び出す
return 0;
}