はじめに
C++のクラスで、全てのメンバを public
(公開)にしてしまうと、クラスの外部から myCar.gas = -10.0;
のように、意図しない不正な値を直接代入できてしまいます。これでは、オブジェクトの状態が簡単におかしくなり、バグの原因となります。
このような問題を防ぐのが、オブジェクト指向の重要な概念である「カプセル化(データの隠蔽)」です。重要なデータ(メンバ変数)は private
(非公開)にして外部から隠し、そのデータを操作するための安全な窓口となる関数(メンバ関数)だけを public
(公開)にします。
この記事では、private
と public
を使い分けて、クラスのメンバへのアクセスを適切に制限し、オブジェクトの安全性を高める方法を解説します。
アクセス制限を実装したサンプルコード
このコードは、Car
クラスのメンバ変数 fuel
(燃料)を private
にし、値を設定するための public
なメンバ関数 setFuel
の中で、値が不正でないかをチェックするロジックを実装します。
完成コード
#include <iostream>
using namespace std;
class Car {
private:
// 1. privateメンバ: 外部から直接アクセスできない
int licenseNumber;
double fuel;
public:
// 2. publicメンバ: 外部からアクセスできる操作の窓口
void showStatus();
void setValues(int num, double gas);
};
// メンバ関数の実装
void Car::showStatus() {
cout << "ナンバーは " << licenseNumber << " です。" << endl;
cout << "燃料は " << fuel << " リットルです。" << endl;
}
// 値を設定するためのセッター関数
void Car::setValues(int num, double gas) {
// 3. 不正な値でないかチェック
if (gas >= 0 && gas <= 100) {
// 条件を満たす場合のみ、privateメンバに値を設定
licenseNumber = num;
fuel = gas;
cout << "ナンバーと燃料を設定しました。" << endl;
} else {
// 不正な値の場合は、エラーメッセージを表示して値を変更しない
cout << gas << " は不正な燃料の値です。" << endl;
cout << "値は変更されませんでした。" << endl;
}
}
int main() {
Car myCar;
// publicなメンバ関数 `setValues` を通じて値を設定
myCar.setValues(1234, 50.5);
myCar.showStatus();
cout << "\n--- 不正な燃料の値(-20.0)を設定してみます ---" << endl;
myCar.setValues(5678, -20.0); // 不正な値なので、メンバ変数は更新されない
// 値が変わっていないことを確認
myCar.showStatus();
// NG: privateメンバに直接アクセスしようとするとコンパイルエラーになる
// myCar.fuel = 999.9; // エラー! fuelはprivateです
return 0;
}
コードの解説
1. private
メンバ
private:
キーワード以降に宣言された licenseNumber
と fuel
は、Car
クラスの外部から直接アクセスすることができなくなります。main
関数の中で myCar.fuel = 999.9;
のように書くと、コンパイルエラーが発生します。
2. public
メンバ
public:
キーワード以降に宣言された showStatus
と setValues
は、クラスの外部(main
関数など)から自由に呼び出すことができる、公開された操作の窓口です。
3. setValues
関数によるデータ保護
private
なメンバ変数 fuel
に値を設定する唯一の方法は、public
な setValues
関数を呼び出すことです。 そして、この setValues
関数の中には、 if (gas >= 0 && gas <= 100)
という**検証ロジック(ガード節)**が組み込まれています。引数として渡された gas
の値が、0から100の範囲内という妥当な値である場合のみ、実際に fuel
メンバ変数への代入が行われます。
このように、データを private
で隠蔽し、public
な関数でアクセスを制御することで、オブジェクトが常に矛盾のない、正しい状態に保たれることを保証できます。これがカプセル化の大きなメリットです。
まとめ
今回は、private
と public
を使い分けて、クラスのメンバへのアクセスを制限する方法を解説しました。
- 重要なデータ(メンバ変数)は
private
にして隠蔽する。 - 外部に提供したい機能(メンバ関数)は
public
にして公開する。 public
な関数の中に検証ロジックを設けることで、private
なデータを不正な値から保護できる。
この「データの隠蔽」と「公開されたインターフェースを通じたアクセス」という考え方が、カプセル化の基本であり、安全で再利用しやすいクラスを設計するための必須のテクニックです。