Skip to main content

ドラクエ風「商人クラス」で学ぶ getter / setter / public / private

🎮 授業進行カンペ+教材一体版

ドラクエ風「商人クラス」で学ぶ getter / setter / public / private


🧭 授業概要

  • 対象:専門学校1年(C++基礎後半中盤

  • 時間:45分 × 1コマ

  • 前提:クラス宣言・メンバ関数の基本を理解しているは既習

  • 目的:getter/setterを使っsetter・public/private の基本構造と目的を理解する

  • 進行:

    1. バグる商人(問題提起)

    2. 安全な商人(getter/setter導入)

    3. 演習問題(小課題+全体レビュー)


🧾 提示する資料(学生閲覧用 DokuWiki ページ)

BookStackからリンクまはQRで提示。学生側にはDokuWiki版をコピ配布。

ページ保護と、public/privateのイトル:

🧭 ドラクエ風「商人クラス」で学ぶ getter / setter / public / private

構成:

  • バグる商人コード(直接代入で壊れる例)

  • 安全な商人コード(getter/setter+private)

  • 解説表:public/private/getter/setter

  • 練習問題5問

  • チェックポイント

提示タイミング:

  • 導入5分で「このページを開いてください」

  • 教員は1つずつ実行例を見せながら口頭解説


🧩 授業構成(45分想定)進行

時間 内容 教員アクション
0〜5分 導入(勇者が商人に話しかける小芝居)バグ実行 勇者が在庫を勝手に増したらくそう−100G」なうなる?」で笑いを取りながら興味づけ
5〜15分 バグる商人コードを実行getter/setterの考え方 あえて m.stock=9999; m.price=-100; 「値の出入口見せて「チート商人関数で管理を演出と板書
15〜25分 getter/setter導入安全な商人コード実行 「値private→public→setterの流れチェックしてから代入する」関数の必要性を強調追う
25〜35分 public/private導入演習問題 「商1〜4を個の金庫は鍵付き!」の比喩で説明、5はグループ討論
35〜40分全体レビューsetterの制限・public/privateを再確認
40〜45分 実装演習まとめ発表次回予告 各自のコンソール出力を見せ合う(「次は勇者バグネタを拾う)(Player)と取引します」

💬 導入教員トーク例

今日はドラクエの“商人”を作ります。やくそうを8Gで売る設定です。」
「ところがこの商人、外から勝手に在庫を増やせるバグがあります!」
2個で始めたのに、勇者が直接 m.stock = 9999;stock=9999 って打っ書いたらどうなると思う?」

→ 学生「無限やくそう!」「最強チートじゃん!」
→ 教員「そう、だから商人の金庫に鍵をかけましょう」
→ ⇒ private へつなげる。


🧩 実演ポイント

1️⃣ バグる商人

  • 実行して「マイナス価格にしたら勇者が儲かる! これはバグ。
    だから金庫(private)に鍵をかけて、店員(getter/setter)を通すんです。「無限


    💻 教示コード(投影または配布用)

    ① バグる商人(問題提起)

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Merchant {
    public:
        string itemName;
        int price;
        int stock;
    
        void Sell() {
            if (stock > 0) {
                stock--;
                cout << itemName << "を" << price << "Gで売った!" << endl;
            } else {
                cout << "在庫」を見せる。

    がない!"
  • <<
  • endl;

    学生の笑いを誘いながら、“危険な状態”を目で見せる。

    }
  • }
};

2️⃣int main() { Merchant m; m.itemName = "やくそう"; m.price = 8; m.stock = 2; m.Sell(); m.Sell(); m.Sell(); m.stock = 9999; // ← 不正操作 m.price = -100; // ← マイナス価格! m.Sell(); }


安全な商人(getter/setter+setter + private)

#include <iostream>
#include <string>
using namespace std;

class Merchant {
private:
    string itemName;
    int price;
    int stock;

public:
    void SetItemName(string name) { itemName = name; }

    void SetPrice(int value) {
        if (value < 0) value = 0;
        if (value > 9999) value = 9999;
        price = value;
    }

    void SetStock(int value) {
        if (value < 0) value = 0;
        stock = value;
    }

    string GetItemName() { return itemName; }
    int GetPrice() { return price; }
    int GetStock() { return stock; }

    void Sell() {
        if (stock > 0) {
            stock--;
            cout << itemName << "を" << price << "Gで売った!" << endl;
        } else {
            cout << "在庫がない!" << endl;
        }
    }
};

int main() {
    Merchant m;
    m.SetItemName("やくそう");
    m.SetPrice(8);
    m.SetStock(2);

    m.Sell();
    m.Sell();
    m.Sell(); // 在庫がない!

    // m.stock = 9999; ← エラー
    // m.price = -100; ← エラー
}

🧩 授業内演習問題(提示用)

Q1

商人クラスに「商品名」「価格」「在庫」を private で定義し、
それぞれに SetGet 関数を作成せよ。

  • Q2

    SetPrice() で価格が 0未満なら09999より大きければ9999 範囲チェック制限せよ。

    Q3

    SetStock() で在庫が マイナスのとき0に補正 されるようにせよ。

    Q4

    main()関数で商人を作成し、やくそうを2個販売するコードを書け。
    (3回目の販売時には「在庫がない!」が出力されること)

    Q5(発展)

    新しいメンバ関数 ShowStatus() を追加し、
    「商品名・価格・在庫」を1行で表示せよ

  • private: を書いた瞬間に「外から触れない」ことを実演。

  • 「勇者が金庫を開けようとして怒られる!」と演出。


🧠 板書例(黒板・スライド)

public : みんなが見えるところ(入口)
private: 秘密の金庫(中身)
---------------------------
getter : 値を読む関数
setter : 値を入れる関数(チェック付き)

💬💡 教員のコメント例

  • 「public は “お店のカウンター”、private は “裏の倉庫”」

  • 「倉庫に勝手に入る勇者は万引き犯!」

  • 「getter/setter は “店員を通して取引する”」


🎯 チェック用解説・ポイント

問題ねらい指導ポイント模範コード抜粋
Q1getter/setter の型と戻り値の対応void SetXxx(T) と T GetXxx() の対称性を意識void SetItemName(string n){itemName=n;}
Q2setter での値検証if文で範囲制限。固定値ではなく変数を渡す形を見せるif(value<0)value=0;
Q3状態の整合性保持在庫は負数で意味を持たない → 0で丸めるif(value<0)value=0;
Q4実行結果の確認出力順に注目。「在庫がない!」が出るまでSell()m.Sell();m.Sell();m.Sell();
Q5状態表示デバッグ・確認に便利。getterの活用を実感させるcout<<"商品:"<<itemName<<" 在庫:"<<stock<<endl;

✅ チェックリスト

  • getter/setterの命名ルール:Get○○() / Set○○()setterで値をチェックできているか

  • 値チェックは setter にまとめるprivate変数を直接触っていないか

  • private 変数はクラス外出力が想定通りらアクセス不可

  • 直接代入の禁止を実演 コードに不正アクセス部分(コメントで残して実感させ)が理解できているか


🧩 練習問題指導メモ発展予告(次回)

  • Q1〜Q3:個人Playerクラスを導入し、SellTo(Player&)実装させる(10分)取引処理

  • Q4:実行出力をペアで見せ合うhas-a関係・参照渡しの導入

  • Q5(発展):2回目授業の導入へ(Playerクラスとの取引)


🧩 よくある質問と返し方

質問回答例
「なんで全部publicでよくないんですか?」「家の金庫を玄関に置かないのと同じ。守るものは隠す!」
「priceをマイナスにしても別に動くけど?」「コンピュータは素直。だから人間がルールを教える。」
「getter/setterだとコード長くない?」「安全のためのコスト。後でバグ直すより安い!」

🪜 次回へのつなぎ方

  • 「商人が複数商品(Item)を複数持つ」→ vectorへ

  • 「プレイヤーと取引」→ has-a 関係対応(vector)

  • 「商品タイプ」→ enum classへ

  • constメンバ関数導入タイミング:次回「情報を読むだけの関数とは?」で扱う展開


🎬 まとめコメント例(授業締めの一言案

プログラムもお店も、“誰でも触れる場所”と“触れちゃダメな場所”があるんです。
今日のゴール目的“商人の金庫に鍵をかける”でした。
直接代入では壊れるようになった”。関数を通せば守れる。
getter/setter こと!は、プログラム世界のルールブックです。