プロジェクトの概要
CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 44/61。
チャレンジ
簡単Shape struct を作成して、Shape Drawer プロジェクトの基盤を整えましょう。これは、function ポインタを通じて、あらゆる shape が実行できることを定義するインターフェースです。
このポリモーフィックなシステムを構築するために、2つのファイルを作成します。
shape.h: ここでコアインターフェースを定義します。まず、Shapestruct の前方宣言を作成します。次に、2つの function ポインタ型を定義します。DrawFunc:const Shape*parameter を受け取り、何も返しませんAreaFunc:const Shape*parameter を受け取り、doubleを返します
Shapestruct 自体を定義します。draw(型はDrawFunc)とarea(型はAreaFunc)です。この struct は純粋にインターフェースとして機能します。shape 固有のデータは保持せず、behavior だけを保持します。main.c: シンプルな test shape を作成して、インターフェースが機能することを実証します。2つの function を Implement します。test_draw:Drawing test shapeを表示しますtest_area:42.0を Returns します
Shapeinstance を Create し、それをこれらの test functions に接続してから、インターフェースを通じて両方を Call します。area の結果を小数点以下1桁で表示します。
出力には、function ポインタが正しく動作することが示されるはずです。
Drawing test shape
Area: 42.0なぜ前方宣言が必要なのでしょうか? typedef struct Shape Shape; が struct の完全な定義の前に現れる理由を疑問に思うかもしれません。これは、DrawFunc と AreaFunc が 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オンラインコンパイラ