ベースクラスと派生クラス


C++を初めて学んだとき、多くの人がいろいろなアクセス番号の下のベースクラスと派生クラスの関係を悩んでいましたが、実際には、ハードバックを暗記するのは良い方法ではないに違いありません.それらの関係を知るには、まずアクセス番号がどのように生成されたのかを分析しなければなりません.
継承されない前に、クラスには2つのユーザーしかいません.クラス自体とクラスのユーザーです.クラスメンバーをpublicとprivateで区分することは、クラスの使用者がクラスのpublic部分にしかアクセスできず、一般的にクラスのインタフェースである.クラスメンバーはpublicにもprivateセクションにもアクセスでき、privateセクションはクラスの具体的な実装です.継承があると、クラスの使用者にはベースクラスの派生クラスというクラスが追加されます.派生クラスは、通常、ベースクラスの特定のインプリメンテーションにアクセスし、一般的なユーザーにこれらのインプリメンテーションにアクセスさせたくないので、これらの内容を一緒に配置し、protectedラベルで説明します.このクラスの使用者の観点から、protectedメンバーはプライベートであり、ベースクラスオブジェクトの保護メンバーにアクセスすることはできませんが、このクラスの継承者の観点から、protectedは派生クラスの使用のために継承されることができるため、共有されています.
派生クラスのベースクラスメンバーへのアクセスをさらに制限するために、C++はまた、アクセスリストのアクセス番号によって制御されます.具体的に言えば
1.継承方式がpublicの場合、ベースクラスのpublicメンバーは派生クラスで常にpublicであり、ベースクラスのprotectedはprotectedであり、ベースクラスのprivateは派生クラスにアクセスできない.
2.継承方式がprotectedの場合、ベースクラスのpublicメンバーは派生クラスでprotectedであり、ベースクラスのprotectedメンバーは派生クラスでprotectedであり、ベースクラスのprivateメンバーは派生クラスでアクセスできない.
3.継承方式がprivateの場合、ベースクラスのpublicメンバーは派生クラスでprivate、ベースクラスのprotectedメンバーは派生クラスでprivate、ベースクラスのprivateメンバーは派生クラスでアクセスできません.
まとめてみます.
 
 
ベースクラス共有メンバー
ベースクラス保護メンバー
ベースクラスプライベートメンバー
公有相続
派生クラスの共有メンバー
派生クラス保護メンバー
派生クラスはアクセスできません
保護継承
派生クラス保護乗員
派生クラス保護乗員
派生クラスはアクセスできません
プライベート継承
派生クラスのプライベートメンバー
派生クラスのプライベートメンバー
派生クラスはアクセスできません
もう1つの例を見てみましょう.
//  
class Base
{
public:
	Base(int i = 0):baseVal_public(i),baseVal_protected(i),baseVal_private(i){}
	int baseVal_public;
	void printVal()
	{
		cout<<baseVal_protected<<endl;
		cout<<baseVal_private<<endl;
	};
protected:
	int baseVal_protected;
private:
	int baseVal_private;

};


//   
class Derived_public:public Base
{
public:
	Derived_public(int i = 0):Base(i){}
	
	void getVal()
	{
		//                 
		cout<<baseVal_public<<endl;
		//               
		cout<<baseVal_protected<<endl;
		//               
		//cout<<baseVal_private<<endl;
	}


};


class Derived_protected:protected Base
{
public:
	Derived_protected(int i = 0):Base(i){}
	void getVal()
	{
		//       、            
		cout<<baseVal_public<<endl;
		cout<<baseVal_protected<<endl;
		//              
		//cout<<baseVal_private<<endl;
	}

};

class Derived_private:private Base
{
public:
	Derived_private(int i = 0):Base(i){}
	void getVal()
	{
		//       、               
		cout<<baseVal_public<<endl;
		cout<<baseVal_protected<<endl;
		//            
		//cout<<baseVal_private<<endl;
	}

};
int main()
{
	
	Base b;
	//           
	cout<<b.baseVal_public<<endl;
	//    、            
	//cout<<b.baseVal_private<<endl;
	//cout<<b.baseVal_protected<<endl;
	//    、             
	b.printVal();

	
	
	//     
	Derived_public d1;
	//   public    public,    
	cout<<d1.baseVal_public<<endl;
	//    ,         、   ,    
	//cout<<d1.baseVal_protected<<endl;
	//cout<<d1.baseVal_private<<endl;
	d1.getVal();
	
	
	//     
	Derived_protected d2;	
	//   public      protected
	//cout<<d2.baseVal_public<<endl;
	//   protected      protected
	//cout<<d2.baseVal_protected<<endl;
	//   private     
	//cout<<d2.baseVal_private<<endl;
	d2.getVal();

	//    
	Derived_private d3;
	//       、             
	//cout<<d3.baseVal_public<<endl;
	//cout<<d3.baseVal_protected<<endl;
	//         
	//cout<<d3.baseVal_private<<endl;
	d3.getVal();
	return 0;
}

プログラムでは、注釈されたコードはすべてエラーを報告します.エラーの原因はこの行のコードの上にあります.ここでは説明しすぎません.
もちろん、アクセスリストのアクセスラベルで制限されていますが、派生クラスにusing宣言を付けることで権限を復元できます(リカバリのみ、向上はできません)
class Derived_private:private Base
{
public:

	Derived_private(int i = 0):Base(i){}
	void getVal()
	{
		//       、               
		cout<<baseVal_public<<endl;
		cout<<baseVal_protected<<endl;
		//            
		//cout<<baseVal_private<<endl;
	}

	using Base::baseVal_public1;

};

それでいい
	cout<<d3.baseVal_public1<<endl;

もう一つ注意しなければならないのは、友元関係が継承と派生後にどのように変化するかということです.
総じて言えば、2つの点に分けられます:1.クラスが別のクラスの友元として付与されている場合、その派生クラスはこのクラスの友元ではありません.2.ベースクラスの友元はベースクラスの派生クラスに役に立たない.例を挙げて説明します.
//    
class Base  
{  
friend class Frnd;  
public:  
    Base(int i = 0):baseVal_private(i){}  
      
private:  
    int baseVal_private;  
  
};  
  
class D1:public Base  
{  
private:  
    int derivedVal;  
  
};  
  
class Frnd  
{  
public:  
    int mem(Base b){return b.baseVal_private;}  
    //                 
    //int mem(D1 d){return d.derivedVal;}  
  
};  
  
class D2:public Frnd  
{  
public:  
    //                       
    //int mem(Base b){return b.baseVal_private;}  
  
};

最後に、class定義の派生クラスを使用している場合は、アクセス番号を書かない場合は、デフォルトの継承関係はprivateです.structで定義された派生クラスを使用してアクセスラベルを書かない場合、デフォルトの継承関係はpublicです.