Menu
Coddy logo textTech

継承のアクセスレベル

CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 49/104。

選択した inheritance の型は、derived class で base class のメンバーにどのようにアクセスできるかに影響します。C++ では、publicprotectedprivate inheritance の3つの選択肢があります。

各タイプがメンバーの access をどのように変換するかは次のとおりです:

Base メンバーpublic inheritanceprotected inheritanceprivate inheritance
publicpublicprotectedprivate
protectedprotectedprotectedprivate
privateinaccessibleinaccessibleinaccessible
class Base {
public:
    int pub;
protected:
    int prot;
private:
    int priv;
};

class PublicDerived : public Base {
    // pub は public、prot は protected、priv はアクセス不可
};

class ProtectedDerived : protected Base {
    // pub は protected、prot は protected、priv はアクセス不可
};

class PrivateDerived : private Base {
    // pub は private、prot は private、priv はアクセス不可
};

Public inheritanceは「is-a」関係をモデル化するもので、はるかに最も一般的です。DogAnimalなので、external codeはそれをAnimalとして扱えます。

protected と private inheritance model 「実装によって実現される」関係です。これらは base class のインターフェースを外部コードから隠すため、inheritance 関係を公開せずに実装を再利用したい場合に便利です。private inheritance では、さらに derived クラスでさえ、元の base メンバーへの access を失います。

challenge icon

チャレンジ

簡単

異なる継承タイプがメンバーへのアクセス可能性にどのような影響を与えるかを、シンプルなデバイス階層を構築して見てみましょう。基本となる Device class と、異なる継承タイプをそれぞれ使用する3つの derived class を作成し、public、protected、private 継承によってメンバーへのアクセスがどのように変化するかを実際に確認します。

コードを2つのファイルに分けて整理します。

  • Device.h: 異なる access level にある3つのメンバーを持つ基本 Device class を define します。
    • public な std::string model
    • protected な int serialNumber
    • private な int internalCode(デフォルトで999に設定)
    • 次を prints する public method showModel(): Model: <model>

    次に、それぞれ異なる継承タイプを使用して Device から継承する3つの derived class を Create します。

    • PublicDevicepublic inheritance を使用): 次を prints する method displaySerial() を追加します: Serial: <serialNumber>
    • ProtectedDeviceprotected inheritance を使用): 次を prints する method displaySerial() を追加します: Serial: <serialNumber>
    • PrivateDeviceprivate inheritance を使用): 次を prints する method displaySerial() を追加します: Serial: <serialNumber>

    各 derived class には、model name と serial number を受け取り、model を base class に渡して serial number を設定する Constructor が必要です。

  • main.cpp: 2つの input を読み取ります(それぞれ別の行に入力)。
    1. Model name(string)
    2. Serial number(integer)

    同じ input values を使用して、各 derived type の object を1つずつ Create します。その後、access の違いを Demonstrate します。

    PublicDevice の場合:

    • object 上で直接 showModel() を Call します(public inheritance によって public のまま保たれるため動作します)
    • model に直接 access し、次を print します: Direct model access: <model>
    • displaySerial() を Call します

    ProtectedDevicePrivateDevice の場合:

    • displaySerial() のみを Call します(継承された showModel()model は、外部からはもはや public に access できません)

    出力形式:

    --- PublicDevice ---
    Model: <model>
    Direct model access: <model>
    Serial: <serial>
    --- ProtectedDevice ---
    Serial: <serial>
    --- PrivateDevice ---
    Serial: <serial>

例えば、input が Laptop12345 の場合:

--- PublicDevice ---
Model: Laptop
Direct model access: Laptop
Serial: 12345
--- ProtectedDevice ---
Serial: 12345
--- PrivateDevice ---
Serial: 12345

PublicDevice だけが、継承された public members への external access を許可していることに注目してください。他の継承タイプでは、base class の interface は外部 code から隠されますが、derived class は独自の method を通じて protected members に内部から access できます。

自分で試してみよう

#include <iostream>
#include <string>
#include "Device.h"

using namespace std;

int main() {
    // 入力を読み取る
    string modelName;
    int serialNum;
    
    getline(cin, modelName);
    cin >> serialNum;
    
    // TODO: 入力値を使って各派生型のオブジェクトを作成する
    // PublicDevice pubDev(modelName, serialNum);
    // ProtectedDevice protDev(modelName, serialNum);
    // PrivateDevice privDev(modelName, serialNum);
    
    // TODO: Demonstrate PublicDevice access
    cout << "--- PublicDevice ---" << endl;
    // - オブジェクトに対して直接 showModel() を呼び出す
    // - Access model directly and print: Direct model access: <model>
    // - displaySerial() を呼び出す
    
    // TODO: Demonstrate ProtectedDevice access
    cout << "--- ProtectedDevice ---" << endl;
    // - displaySerial() のみを呼び出す(showModel と model は公開アクセスできない)
    
    // TODO: Demonstrate PrivateDevice access
    cout << "--- PrivateDevice ---" << endl;
    // - displaySerial() のみを呼び出す(showModel と model は公開アクセスできない)
    
    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: C++オンラインコンパイラ