15:クラス設計 総まとめ演習

はじめに

ここまで学んだ「クラス」「コンストラクタ」「アクセス修飾子」をしっかり理解するため、
コピー元コードを改良する演習問題を提示します。
新しい知識は不要なので、これまでの復習として取り組みましょう。


演習問題(15_account_refactor.cpp)

元のコード
#include <iostream>
using namespace std;

class Account {
public:
    int balance;

    void deposit(int amount) {
        balance += amount;
    }

    void show() {
        cout << "残高: " << balance << "円" << endl;
    }
};

int main() {
    Account a;
    a.balance = 0;
    a.deposit(500);
    a.show();

    return 0;
}
改善指示
  1. balance(残高)をインスタンスから直接アクセスできないように private にする
  2. コンストラクタで初期残高を設定できるようにする
  3. deposit() 関数と show() 関数はそのまま使えるようにする
  4. 出金用の pay(int) 関数を作る
  5. 出金可能かどうかを確認する bool paycheck(int) 関数を作る
  6. main() で残高500円からスタートし、出金可能なら支払いし、そうでなければ失敗メッセージを表示し、最後に残高を表示する
解答例と解説を見る
// 15_account_refactor.cpp
#include <iostream>
using namespace std;

class Account {
private:
    int balance;

public:
    Account(int initial) {
        balance = initial;
    }

    void deposit(int amount) {
        balance += amount;
    }

    void pay(int amount) {
        balance -= amount;
        cout << amount << "円を出金しました。" << endl;
    }

    bool paycheck(int amount) {
        return balance >= amount;
    }

    void show() {
        cout << "残高: " << balance << "円" << endl;
    }
};

int main() {
    Account a(500);
    a.deposit(300);

    if (a.paycheck(200)) {
        a.pay(200);
    } else {
        cout << "200円の出金に失敗しました。" << endl;
    }

    if (a.paycheck(700)) {
        a.pay(700);
    } else {
        cout << "700円の出金に失敗しました。" << endl;
    }

    a.show();

    return 0;
}

解説


演習問題(15_rectangle_refactor.cpp)

元のコード
#include <iostream>
using namespace std;

class Rectangle {
public:
    int width;
    int height;

    int area() {
        return width * height;
    }
};

int main() {
    Rectangle r;
    r.width = 5;
    r.height = 3;
    cout << "面積: " << r.area() << endl;

    return 0;
}
改善指示
  1. widthheightprivate に変更する
  2. デフォルトサイズ(1×1)と任意サイズの両方に対応するよう、コンストラクタをオーバーロードする
  3. 面積を求める関数 area() はそのまま使えるようにする
  4. main() 関数で、デフォルトサイズとサイズ指定の両方のオブジェクトを生成して面積を表示する
解答例と解説を見る
// 15_rectangle_refactor.cpp
#include <iostream>
using namespace std;

class Rectangle {
private:
    int width;
    int height;

public:
    Rectangle() : width(1), height(1) {}
    Rectangle(int w, int h) : width(w), height(h) {}

    int area() {
        return width * height;
    }
};

int main() {
    Rectangle r1;
    Rectangle r2(5, 3);

    cout << "r1の面積: " << r1.area() << endl;
    cout << "r2の面積: " << r2.area() << endl;

    return 0;
}

演習問題(15_product_refactor.cpp)

元のコード
#include <iostream>
using namespace std;

class Product {
public:
    string name;
    int price;

    void show() {
        cout << name << " は " << price << " 円です。" << endl;
    }
};

int main() {
    Product p;
    p.name = "りんご";
    p.price = 150;
    p.show();

    return 0;
}
改善指示
  1. namepriceprivate に変更する
  2. コンストラクタで商品名と価格を指定できるようにする
  3. show() 関数はそのまま使えるようにする
  4. main() 関数でインスタンスを生成し、正しく表示されることを確認する
解答例と解説を見る
// 15_product_refactor.cpp
#include <iostream>
using namespace std;

class Product {
private:
    string name;
    int price;

public:
    Product(string n, int p) : name(n), price(p) {}

    void show() {
        cout << name << " は " << price << " 円です。" << endl;
    }
};

int main() {
    Product p("りんご", 150);
    p.show();

    return 0;
}