まとめ:秘密の箱
CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 21/61。
チャレンジ
簡単完全なカプセル化を示す Box モジュールを構築しましょう。box には、width、height、depth という3つの隠された dimensions があり、提供する関数を通してのみアクセスできます。これが、完全な opaque pointer パターンの実例です!
3つのファイルを作成します。
box.h: パブリックインターフェースです。forward declaration のみを使用して opaque なBox型を Declare します。struct の本体は隠されたままです。次の関数を Declare します。create_box: 3つの整数(width、height、depth)を受け取り、Box ポインターを返しますdestroy_box: Allocate されたメモリを Free しますget_volume:const Box *を受け取り、volume(width × height × depth)を返しますset_dimensions: Box ポインターと3つの新しい dimension の値を受け取り、intを返します(成功時は1、いずれかの dimension が負または zero の場合は0)
BOX_Hを使用して include guards を設定します。box.c: 3つの隠された members、int width、int height、int depthを持つ実際のstruct Boxを Define します。4つの関数すべてを Implement します。constructor は box を Allocate して initialize する必要があります。set_dimensions関数は、3つすべての値が positive(zero より greater)であることを validation してから変更を適用する必要があります。いずれかの値が validation に fails した場合は、更新全体を reject して0を返します。main.c: カプセル化された Box を1つ Create し、その volume を確認し、dimensions の変更(valid と invalid の両方)を attempt し、適切に cleanup することで実演します。
5つの入力を受け取ります。initial width、initial height、initial depth に続いて、設定を attempt する3つの新しい dimensionsです(invalid な値を含む場合があります)。
main ファイルで initial dimensions を使用して Box を Create し、その volume を print します。次に新しい dimensions の設定を attempt し、更新が成功したかどうかと結果の volume を print します。最後に box を Free し、cleanup を確認します。
次の形式で output を print します。
Volume: {volume}
Set: {0 or 1}
Volume: {volume}
Destroyedたとえば、入力が 2、3、4、5、5、5 の場合、output は次のようになります。
Volume: 24
Set: 1
Volume: 125
Destroyed入力が 2、3、4、-1、5、5 の場合、output は次のようになります。
Volume: 24
Set: 0
Volume: 24
Destroyedset_dimensions の validation がどのように box を invalid な状態から保護しているかに注目してください。dimensions はインターフェースの背後に完全に隠されているため、external code はルールを bypass できません。
自分で試してみよう
#include <stdio.h>
#include "box.h"
int main() {
// 初期の寸法を読み取る
int width, height, depth;
scanf("%d", &width);
scanf("%d", &height);
scanf("%d", &depth);
// 試行する新しい寸法を読み取る
int new_w, new_h, new_d;
scanf("%d", &new_w);
scanf("%d", &new_h);
scanf("%d", &new_d);
// TODO: 初期の寸法で Box を作成する
// TODO: 初期の体積を次の形式で出力する: "Volume: {volume}"
// TODO: 新しい寸法の設定を試み、結果を保存する
// TODO: 設定が成功したかどうかを次の形式で出力する: "Set: {0 or 1}"
// TODO: 結果の体積を次の形式で出力する: "Volume: {volume}"
// TODO: box を破棄し、"Destroyed" を出力する
return 0;
}
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Cオンラインコンパイラ