Menu
Coddy logo textTech

ゲッターとセッター

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

opaque ポインターを使用すると、struct の member は外部のコードから隠されます。しかし、外部のコードがデータに直接アクセスできない場合、どうやってそれを読み取ったり変更したりするのでしょうか?答えは getter 関数と setter 関数です。これらは、private データへの制御されたアクセスを提供する public インターフェースです。

getterは非公開のメンバーの値を返します:

// counter.h
int counter_get_value(const Counter *c);

// counter.c
int counter_get_value(const Counter *c) {
    return c->value;
}

setterは非公開のメンバーを変更します。

// counter.h
void counter_set_value(Counter *c, int new_value);

// counter.c
void counter_set_value(Counter *c, int new_value) {
    c->value = new_value;
}

命名規則に注目してください。競合を避け、APIを明確にするため、関数名には型名(counter_)を接頭辞として付けています。getterではオブジェクトを変更しないため、constポインターを使用します。

これで、外部コードは隠されたデータと安全にやり取りできます。

// main.c
Counter *c = create_counter(10);
printf("%d\n", counter_get_value(c));  // 10
counter_set_value(c, 25);
printf("%d\n", counter_get_value(c));  // 25

このpatternによって、データへのアクセス方法を完全に制御できます。これは、次のレッスンでセッターに検証ロジックを追加する際に、その上に構築していく基盤となります。

challenge icon

チャレンジ

簡単

getter 関数と setter 関数を使用する opaque pointer pattern を使って、Score モジュールを作成しましょう。外部コードが、提供する public interface を通してのみデータを操作できる、隠蔽された score tracker を作成します。

3 つのファイルを作成します。

  • score.h:public interface です。forward declaration を使用して opaque な Score 型を Declare します(struct body は記述しません!)。次の関数を Declare します。
    • create_score:initial points を表す integer を受け取り、Score pointer を returns します
    • free_score:Score pointer を受け取り、memory を解放します
    • score_get_pointsconst Score * を受け取り、現在の points を returns する getter です
    • score_set_pointsScore * と integer を受け取り、points の値を更新する setter です
    SCORE_H シンボルを使用して include guards を実装します。
  • score.c:単一の隠された member である int points を持つ実際の struct Score を Define します。4 つの関数をすべて Implement します。getter は隠された値を return し、setter はその値を更新します。getter は object を変更しないため const pointer を使用することを Remember してください。
  • main.c:Score を作成し、その値を読み取り、setter を通して変更し、もう一度読み取ることでモジュールを実演します。

2 つの入力を受け取ります。initial points(integer)と、設定する new points value(integer)です。

main file で initial points を使って Score を作成し、getter を使用して現在の値を Print し、setter と new value を使って更新し、更新後の値を Print します。その後、score を Free して確認メッセージを Print します。

次の形式で出力します。

Initial: {points}
Updated: {points}
Freed

たとえば、入力が 100250 の場合、出力は次のようになります。

Initial: 100
Updated: 250
Freed

main.cpoints に直接アクセスできないことに注目してください。getter と setter の関数を通す必要があります。これが encapsulation の実例です。隠されたデータをどのように読み取り、変更できるかを正確に制御できます。

自分で試してみよう

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

int main() {
    int initial_points, new_points;
    scanf("%d", &initial_points);
    scanf("%d", &new_points);
    
    // TODO: initial_points で Score を作成する
    
    // TODO: getter を使用して初期値を出力する
    // 形式: "Initial: {points}"
    
    // TODO: setter を使用して new_points でスコアを更新する
    
    // TODO: getter を使用して更新後の値を出力する
    // 形式: "Updated: {points}"
    
    // TODO: スコアを解放して "Freed" を出力する
    
    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

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

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