オブジェクトとしての構造体
CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 6/61。
オブジェクト指向言語では、オブジェクトとは、データ(状態)と、そのデータを操作する関数(メソッド)をひとまとめにしたエンティティです。Cには組み込みのオブジェクトはありませんが、構造体と関数を使って同じ概念を実現できます。
struct はオブジェクトの「data」部分だと考えてください。オブジェクトの状態、つまり現在のオブジェクトが何であるかを定義する値を保持します。
typedef struct {
int value;
} Counter;
この Counter 構造体は、単一の状態、つまり its current value を持つエンティティを表します。これに振る舞いを与えるため、構造体をパラメーターとして受け取る関数を記述します。
void counter_increment(Counter *c) {
c->value++;
}
int counter_get(Counter *c) {
return c->value;
}
これらの関数はメソッドのように機能します。Counter データに対して具体的に動作します。struct を関数に渡すことで、counter.increment() を呼び出したときに他の言語が自動的に行う処理をシミュレートしています。
int main() {
Counter my_counter = {0};
counter_increment(&my_counter);
printf("%d\n", counter_get(&my_counter)); // 出力: 1
return 0;
}
typename_action(counter_incrementのようなもの)という命名規則は、コードを整理し、どのstructに関数が属しているかを明確にするのに役立ちます。このパターンは、Cにおけるオブジェクト指向プログラミングの基礎です。
チャレンジ
簡単データを操作する function とともに struct をオブジェクトとして扱う、シンプルな Counter モジュールを作成しましょう。データと、それを操作する function をまとめるパターンを練習するため、コードを3つのファイルに分けて整理します。
3つのファイルを作成します。
counter.h:Counterstruct を宣言するヘッダーファイルです。struct には単一のint valuemember があります。また、counter の "methods" として機能する2つの function も宣言します。counter_increment(Counter への pointer を takes、value を1 increases)と、counter_get(Counter への pointer を takes、current value を returns)です。シンボルCOUNTER_Hを使用して include guards を設定します。counter.c:両方の function を実装するソースファイルです。header file を include することを忘れないでください。main.c:Counter を Create し、それに対して操作を実行して、result を表示する main file です。
counter の starting value と、increment する number of times という2つの整数入力を受け取ります。
main file で、starting value を使って Counter を initialize し、指定された回数だけ counter_increment を Call します。最後に、counter_get を使用して Final value を retrieve し、print します。
result を次の形式で Print します。
Final value: {result}たとえば、starting value が 5 で、3 回 increases する場合、出力は次のようになります。
Final value: 8自分で試してみよう
#include <stdio.h>
#include "counter.h"
int main() {
// 入力を読み取る
int starting_value;
int num_increments;
scanf("%d", &starting_value);
scanf("%d", &num_increments);
// TODO: Counterを作成し、starting_valueで初期化する
// TODO: 指定された回数だけcounter_incrementを呼び出す
// TODO: counter_getを使用して最終値を取得し、出力する
// 出力形式: "Final value: {result}"
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Cオンラインコンパイラ