目次
はじめに
C++のクラスには、メンバへのアクセスを制御するための3つのアクセス指定子があります。
public
: 誰でもアクセス可能(公開)private
: そのクラスの内部からのみアクセス可能(非公開)protected
: そのクラスの内部、およびそのクラスを継承した子クラスからのみアクセス可能(限定公開)
public
と private
はクラスの基本的なカプセル化で使いますが、protected
は、クラスの継承において、親子間で特別な関係を築くために使われます。
この記事では、protected
の役割と、public
/ private
との違いを、具体的なサンプルコードで解説します。
protected
を使ったサンプルコード
このコードは、Vehicle
(乗り物)という親クラスと、それを継承した Car
(車)という子クラスを定義します。親クラスに public
, private
, protected
の3種類のメンバを持たせ、子クラスからどれにアクセスできるかを確認します。
完成コード
#include <iostream>
#include <string>
using namespace std;
// --- 親クラス(基底クラス) ---
class Vehicle {
private:
string secretCode = "v-secret"; // privateメンバ
protected:
int speed = 0; // protectedメンバ
public:
string name = "乗り物"; // publicメンバ
};
// --- 子クラス(派生クラス) ---
class Car : public Vehicle {
public:
void accelerate() {
// publicメンバ(name)には、子クラスからアクセス可能
cout << name << "が加速します。" << endl;
// protectedメンバ(speed)には、子クラスからアクセス可能
speed += 10;
cout << "現在の速度: " << speed << "km/h" << endl;
// privateメンバ(secretCode)には、子クラスからアクセスできない!
// cout << secretCode; // ← この行はコンパイルエラーになる
}
};
int main() {
Car myCar;
myCar.name = "マイカー"; // OK: publicメンバは外部からアクセス可能
// NG: protectedメンバは、クラスの外部からはアクセスできない!
// myCar.speed = 50; // ← この行はコンパイルエラーになる
// NG: privateメンバは、もちろん外部からアクセスできない!
// myCar.secretCode = "new-code"; // ← この行はコンパイルエラーになる
myCar.accelerate();
return 0;
}
コードの解説とアクセスの可否
private
メンバ (secretCode
)
private
で宣言されたメンバは、そのクラスの内部 (Vehicle
クラスの中) でしか使えません。- 子クラス (
Car
) からも、main
関数のようなクラスの外部からも、一切アクセスすることはできません。これは最も厳しいアクセス制限です。
protected
メンバ (speed
)
protected
で宣言されたメンバは、Vehicle
クラスの内部と、それを継承したCar
クラスの内部の両方からアクセスできます。Car
クラスのaccelerate
関数が、speed += 10;
のように直接speed
を操作できているのは、speed
がprotected
だからです。- しかし、
main
関数のようなどちらのクラスにも属さない外部からは、myCar.speed = 50;
のようにアクセスすることはできません。
public
メンバ (name
)
public
で宣言されたメンバは、どこからでも自由にアクセスできます。- 親クラス、子クラス、そして
main
関数のような外部からも、読み書きが可能です。
アクセス可否のまとめ
アクセス指定子 | クラスの外部から | 子クラスの内部から |
public | OK | OK |
protected | NG | OK |
private | NG | NG |
protected
は、「外部には公開したくないが、子クラスには特別な権限を与えて、直接アクセスさせたい」という、親子間の密な連携を実現するためのアクセス指定子と言えます。
まとめ
今回は、C++の protected
アクセス指定子の役割と、継承におけるその振る舞いを解説しました。
protected
は、子クラスからのアクセスは許可するが、それ以外の外部からのアクセスは禁止する。- クラスの基本的なカプセル化は
private
とpublic
で行い、継承関係におけるより詳細なアクセス制御が必要な場合にprotected
を使う。
この3つのアクセス指定子を適切に使い分けることで、より安全で、かつ拡張しやすいクラス階層を設計することができます。