Menu
Coddy logo textTech

プロジェクトの概要

CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 44/61。

challenge icon

チャレンジ

簡単

Shape struct を作成して、Shape Drawer プロジェクトの基盤を整えましょう。これは、function ポインタを通じて、あらゆる shape が実行できることを定義するインターフェースです。

このポリモーフィックなシステムを構築するために、2つのファイルを作成します。

  • shape.h: ここでコアインターフェースを定義します。まず、Shape struct の前方宣言を作成します。次に、2つの function ポインタ型を定義します。
    • DrawFunc: const Shape* parameter を受け取り、何も返しません
    • AreaFunc: const Shape* parameter を受け取り、double を返します
    最後に、2つの function ポインタを含む Shape struct 自体を定義します。draw(型は DrawFunc)と area(型は AreaFunc)です。この struct は純粋にインターフェースとして機能します。shape 固有のデータは保持せず、behavior だけを保持します。
  • main.c: シンプルな test shape を作成して、インターフェースが機能することを実証します。2つの function を Implement します。
    • test_draw: Drawing test shape を表示します
    • test_area: 42.0 を Returns します
    Shape instance を Create し、それをこれらの test functions に接続してから、インターフェースを通じて両方を Call します。area の結果を小数点以下1桁で表示します。

出力には、function ポインタが正しく動作することが示されるはずです。

Drawing test shape
Area: 42.0

なぜ前方宣言が必要なのでしょうか? typedef struct Shape Shape; が struct の完全な定義のに現れる理由を疑問に思うかもしれません。これは、DrawFuncAreaFunc が parameter 型で const Shape* を参照している一方、その時点ではコンパイラーが完全な struct の定義をまだ見ていないため必要です。前方宣言はコンパイラーに「Shape という名前の struct が存在する」と伝えます。これだけで、そのポインタを使用できます。完全な定義は後に続きます。このパターンは、struct が自分自身を直接、または function ポインタを通じて参照する必要がある場合に、C でよく使われます。

ここでの重要なポイントは、Shape は circle や rectangle について何も知らないということです。あらゆる shape が自分自身を draw し、area を計算できなければならないことだけを知っています。今後のレッスンでは、この base struct を埋め込み、それぞれ独自の実装を提供する具体的な shape を Create します。header file では include guards を使用することを忘れないでください。

自分で試してみよう

#include <stdio.h>
#include "shape.h"

// TODO: test_draw 関数を実装する
// - const Shape* パラメータを取る
// - Prints "Drawing test shape"
void test_draw(const Shape* shape) {
    // TODO: 必要なメッセージを出力する
}

// TODO: test_area 関数を実装する
// - const Shape* パラメータを取る
// - 42.0 を返す
double test_area(const Shape* shape) {
    // TODO: テスト用の面積値を返す
}

int main() {
    // TODO: Shape インスタンスを作成する
    
    // TODO: shape を test_draw と test_area 関数に接続する
    
    // TODO: インターフェース経由で draw を呼び出す
    
    // TODO: インターフェース経由で area を呼び出し、小数点以下1桁で出力する
    // フォーマット: "Area: %.1f\n"
    
    return 0;
}

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Cオンラインコンパイラ