C++ の基礎 : アクセス制限
アクセス制限
クラスのメンバ変数やメンバ関数には、public, protected, private という 3 種類のアクセス制限をかけることができます。
【Java では】Java でも public, protected, private という 3 種類のアクセス制限があり、その意味は C++ とほとんど同じです。
public メンバ
たとえば、ここに自動車があるとしましょう。この自動車はスピードが増すにつれて車体の色が変化していくという面白い性質を持っています。これを Car クラスとして表現してみましょう。
class Car { public: // 外部から自由にアクセスできます Color color; SIntN speed; };
Car クラスは車体の色を表す color というメンバ変数と、現在のスピードを表す speed というメンバ変数をもっています。これらのメンバ変数は public というアクセス制限の中で宣言されているため、外部のプログラム コードから自由に読み書きすることが可能です。しかし、これらの変数の値を勝手に書き換えられてしまっては、この自動車のもつ面白い性質を表現できません。color は speed と連動して変化しなければならないからです。
private メンバ
こういう場合、color と speed の 2 つのメンバ変数を、private というアクセス制限の中で宣言します。Car クラスを利用する外部プログラムは、private アクセス制限をもつメンバ変数を読み書きすることはできません。
class Car { private: // 外部からアクセスすることはできませんColor color; SIntN speed; };
たとえば、次のようなプログラムを書くと、コンパイル時にエラーになります。
Car car; car.speed = 100; // private メンバ変数にはアクセスできません
アクセッサ
メンバ変数に読み書きできないのであれば、それではどうやって、スピードと車体の色を設定したらよいのでしょう? スピードを設定するためのメンバ関数を用意すればよいのです。
class Car { private: // 外部からアクセスできません Color color; SIntN speed; public: // 外部から自由にアクセスできます Void SetSpeed(SIntN s) { speed = s; color.r = s; color.g = s / 2; color.b = 255 - s; } SIntN GetSpeed() { return speed; } Color GetColor() { return color; } };
ここでは SetSpeed() というメンバ関数を用意することで、スピードの設定を間接的に行っています。また、スピードを設定すると同時に車体の色を変化させています。
スピードを取得するには、GetSpeed() 関数を使用します。この関数は内部の private メンバ変数を値を返しているだけです。
また GetColor() というメンバ関数を用意することで、color 変数を間接的に読み取れるようにしています。しかし、color 変数に値を設定することはできません。
これらのメンバ関数はいずれも public アクセス制限の中で宣言されているため、外部のコードから呼び出すことができます。このように、外部から呼び出すことができ、内部のメンバ変数に読み書きする働きをする関数のことをアクセッサといいます。
Car car; car.SetSpeed(100);
メンバ関数を private にすることもできます。private メンバ関数はクラスの内部からのみ呼び出すことができ、クラスの外部から呼び出すことはできません。たとえば、上記の Car クラスは次のように実装することもできます。
class Car { private: // 外部からアクセスできません Color color; SIntN speed; Void SetColor(UInt08 r, UInt08 g, UInt08 b) { color.r = r; color.g = g; color.b = b; } public: // 外部から自由にアクセスできます Void SetSpeed(SIntN s) { speed = s; SetColor(s, s / 2, 255 - s); } SIntN GetSpeed() { return speed; } Color GetColor() { return color; } };
このような場合、Car::UpdateColor() 関数は外部から呼び出すことはできません。
Car car; car.UpdateColor(0,0,0); // コンパイル エラーになります
protected メンバ
public と private については理解できたでしょうか。アクセス制限にはもう1つ protected というのがあります。これは後の章で解説する「継承」に関わってきますので、そのときに説明することにします。
この章のまとめ
- クラスのメンバには public, protected, private という 3 種類のアクセス制限を指定できます。
- public メンバには、クラス外部から自由にアクセスできます。
- private メンバには、クラス外部からアクセスすることはできません。
- private メンバ変数に外部からアクセスするためには、アクセッサを使います。
やってみよう
次のようなコードを実行してみましょう! どのような結果になるでしょうか?
Car クラスの speed メンバ変数に直接アクセスできないことを確かめましょう。
どのようなエラーが表示されるでしょうか?
Void TestAccess(Void) { Car car; Color color; car.SetSpeed(100); color = car.GetColor(); SFXHelper::dbgprintf("Car: r=%d, g=%d, b=%d", color.r, color.g, color.b); //car.speed = 100; // コンパイル エラーになります }