はじめに
C++の継承では、子クラスは親クラスのメンバを引き継ぎますが、全てのメンバに自由にアクセスできるわけではありません。親クラスのメンバが public
, protected
, private
のどれで宣言されているかによって、子クラスの内部から、またクラスの外部からアクセスできる範囲が厳密に決まっています。
この記事では、public
継承を前提として、親クラスのメンバへのアクセス可否がどのように決まるのかを、RPGのキャラクターを例に解説します。
メンバへのアクセス可否 サンプルコード
このコードは、Character
(親クラス)と Hero
(子クラス)を定義し、子クラスの内部 (showHeroStatus
関数) と、クラスの外部 (main
関数) から、親クラスの各メンバにアクセスを試みます。
完成コード
#include <iostream>
#include <string>
using namespace std;
// --- 親クラス(基底クラス) ---
class Character {
private:
string secretItem = "秘密のアイテム"; // private: このクラス内のみ
protected:
int defense = 10; // protected: このクラス + 子クラス内のみ
public:
string name = "キャラクター"; // public: どこからでもOK
};
// --- 子クラス(派生クラス) ---
class Hero : public Character {
public:
void showHeroStatus() {
cout << "--- ステータス表示 ---" << endl;
// OK: 親のpublicメンバには、子クラスからアクセス可能
cout << "名前: " << name << endl;
// OK: 親のprotectedメンバには、子クラスからアクセス可能
cout << "守備力: " << defense << endl;
// NG: 親のprivateメンバには、子クラスからアクセスできない!
// cout << "秘密のアイテム: " << secretItem << endl; // コンパイルエラー!
}
};
int main() {
Hero myHero;
// OK: publicメンバは、外部からアクセス可能
myHero.name = "勇者";
cout << "主人公の名前は " << myHero.name << " です。" << endl;
// NG: protectedメンバは、外部からはアクセスできない!
// myHero.defense = 100; // コンパイルエラー!
// NG: privateメンバは、もちろん外部からもアクセスできない!
// myHero.secretItem = "伝説の剣"; // コンパイルエラー!
myHero.showHeroStatus();
return 0;
}
アクセスのルール (public
継承の場合)
1. 親クラスの public
メンバ
- 子クラスの内部から: アクセス可能 (
showHeroStatus
内でname
を利用) - クラスの外部から: アクセス可能 (
main
内でmyHero.name
を利用)
public
メンバは、誰でも自由に使える、完全に公開された機能です。
2. 親クラスの protected
メンバ
- 子クラスの内部から: アクセス可能 (
showHeroStatus
内でdefense
を利用) - クラスの外部から: アクセス不可能 (
main
内でmyHero.defense
にアクセスしようとするとエラー)
protected
メンバは、親子(とその子孫)の間だけで共有される、いわば「家族内の秘密」です。外部には公開したくないが、子クラスにはより柔軟なアクセスを許可したい場合に利用します。
3. 親クラスの private
メンバ
- 子クラスの内部から: アクセス不可能 (
showHeroStatus
内でsecretItem
にアクセスしようとするとエラー) - クラスの外部から: アクセス不可能
private
メンバは、そのクラス自身だけが知っている「個人的な秘密」です。たとえ親子関係であっても、子クラスが親のプライベートな部分に干渉することは許されません。
アクセス可否のまとめ
親クラスのメンバ | 子クラスの内部からアクセス | クラスの外部からアクセス |
public | OK | OK |
protected | OK | NG |
private | NG | NG |
まとめ
今回は、継承におけるメンバへのアクセス制御について解説しました。
- 子クラスから親クラスのメンバにアクセスできるかは、親クラスでのアクセス指定子によって決まる。
- 親の**
private
**メンバには、子クラスはアクセスできない。 - 親の**
protected
**メンバには、子クラスはアクセスできるが、外部からはアクセスできない。
このアクセス制御の仕組みを理解し、適切に public
, protected
, private
を使い分けることが、カプセル化の原則を守り、安全で拡張しやすいクラス階層を設計する上で非常に重要です。