C++プログラムの世界に入る---私有継承


プライベート継承:
   
C++プログラミング言語では、派生クラスを宣言する際にベースクラスの継承方式をprivateと指定することをプライベート継承と呼び、プライベート継承方式で構築された派生クラスをプライベート派生クラス(private derived class)と呼び、そのベースクラスをプライベートベースクラス(private base class)と呼ぶ.
プライベート・ベース・クラスの共通メンバーと保護メンバーのプライベート・派生クラスでのアクセス・プロパティは、派生クラスのプライベート・メンバーに相当します.つまり、派生クラスのメンバー関数はアクセスできますが、派生クラス以外ではアクセスできません.プライベート・ベース・クラスのプライベート・メンバーは、派生クラスでアクセスできないメンバーと呼ばれます.ベース・クラスのメンバー関数のみが参照できます.ベース・クラスのアクセス・プロパティとプライベート・派生クラスのアクセス・プロパティが異なる場合があります.プライベート・ベース・クラスのメンバーのプライベート派生クラスへのアクセス・プロパティは、次の表を参照してください.
プライベートベースクラスのメンバー
プライベート派生クラスでのアクセス属性
プライベートメンバー
共通メンバー
メンバーの保護
アクセス不可
プライベート
プライベート
具体的には、次のコードを参照してください.
/*
 *private_interitance.cpp
 *Date : 2013-9-20
 *Author: sjin
 *Mail:[email protected]
 */
#include <iostream>
using namespace std;
/*    
 *   public protected     private         ,    
 * private       。                public protected
 *  ,         privated  ,                 
 * */
/*  :    */
class ElectricMotor{
public:
    ElectricMotor(){};
    virtual ~ElectricMotor(){};

public:
    void StartMotor(){
        Accelerate();
        Cruise();
    }

    void StopMotor(){
        cout << " Motor stopped" << endl;
    }

private:
    void Accelerate(){
        cout << " Motor started" << endl;
    }

    void Cruise(){
        cout << "Motor runnung at constant speed " << endl;
    }

};

/*   */
#if 0
class Fan : private ElectricMotor{
public:
    Fan(){};
    virtual ~Fan(){};

    void StartFan(){
        StartMotor();
    }

    void StopFan(){
        StopMotor();
    }

};
#else
/*       (  )
 *
 * */
class Fan {
public:
    Fan(){};
    virtual ~Fan(){};

    void StartFan(){
        m_ElectricMotor.StartMotor();
    }

    void StopFan(){
       m_ElectricMotor.StopMotor();
    }
private:
    ElectricMotor m_ElectricMotor;

};

#endif

int main()
{
    Fan mFan;

    mFan.StartFan();
    mFan.StopFan();

    //mFan.Accelerate();
    //ElectricMotor * pmoto = &mFan;
    /*
    private_inheritance.cpp: In function ‘int main()’:
        private_inheritance.cpp:32: error: ‘void ElectricMotor::Accelerate()’ is private
        private_inheritance.cpp:65: error: within this context
        private_inheritance.cpp:65: error: ‘ElectricMotor’ is not an accessible base of ‘Fan’
        private_inheritance.cpp:66: error:
        */
}

出力:
Motor started
Motor runnung at constant speed 
 Motor stopped

コンパイル中にmain関数の最後の2行のコメントが削除されると、コンパイルエラーが発生します.具体的なエラー情報は主に以下の原則に違反しています.
ベースクラスのpublic protectedメンバーはprivateとして派生クラスに表示されますが、ベースクラスのprivateメンバーはアクセスできません.派生クラスのメンバー関数は、ベースクラスpublic protectedメンバーに直接アクセスできますが、蓄積されたprivatedメンバーにはアクセスできません.派生クラスのオブジェクトはベースクラスのメンバーにアクセスできません.
プライベート継承と集約(組合せ)
class Fan {
public:
    Fan(){};
    virtual ~Fan(){};

    void StartFan(){
        m_ElectricMotor.StartMotor();
    }

    void StopFan(){
       m_ElectricMotor.StopMotor();
    }
private:
    ElectricMotor m_ElectricMotor;

};
には、継承クラスの変更が記載されています.ElectricMotorは、ElectricMotorからFanを派生させるのではなく、Fanのプライベートメンバーとして機能します.これは重合または組合せとなる.
プライベート継承を使用するのと比較して、集約を使用する2つの明らかでない利点は、継承された階層セグメントを除去した後、「虚メソッドを使用する代価」を回避し、パフォーマンスを向上させることです.
プライベート継承には、次のいくつかの利点があります.
1、派生クラスがベースクラスの保護メンバー関数にアクセスできる;
2、派生クラスはベースクラスの虚関数を上書きすることができる.
しかし、これらの利点は以下の代価を伴う.
1、マルチプログラマーのプログラミングでは、コードの柔軟性が低く、エラーが発生しやすい.
2、継承によるパフォーマンスの問題.
したがって、集約が使用可能な場合は、プライベート継承は使用しないでください.