若干間が空きましたが
第6回はクラスの継承についてです。
あと、第5回のほうに補足として
可変長配列の使い方を載せました。

継承を一言で表現することはできませんが
継承することで親のクラスの機能(変数、関数)などを
子のクラスが引き継いだり、
ポリモーフィズム(多様性)というものを表現できたりします。

多様性については説明するよりも
プログラムを起動してみたほうが早いので
次回ソースとともに説明しようと思っています

今回は継承による
機能の引継ぎのところから説明します

とりあえず、継承クラスの書き方から・・・

Parentクラスを親に持つ
Childという名の継承クラスの書き方は
public継承の場合

 class Child:public Parent
 {
 };

と書きます
(protected継承というのもありますが、あとで説明)

クラスのpublicやprivateのキーワードについては
若干触れたと思います
クラスのprivateな変数や関数は外部(mainなど)からアクセスできない
publicな変数や関数ならばどこからでもアクセスできる
今回はprotectedというキーワードが出てきます
こいつは親のクラスと継承したクラス(外部からはアクセス不可)で使える変数、関数を指定します

わざわざ、アクセスのキーワードをつけるのは
意図しないところで変数などの書き換えを防ぐためです
(これをカプセル化といいます)
まぁ、変数の保守性とか安全性とか考えなきゃ
全部publicにしちゃえばいいんだけどさ・・・

まず、アクセスキーワードによってどこからアクセスできるのかを見てみましょう
次のソースにどこからアクセスできるのかすべてまとめてみました
詰め込みすぎて若干わかりにくいかもしれませんが・・・

 // クラスの継承
 
 #include <iostream>
 using namespace std;
 
 // 基本クラス(Childの親クラス)
 class Parent
 {
 // private部は自分のクラス外では一切使えない
 private:
	int a;				// Parentクラス内のみで使える変数
	void TestPrivate()		// Parentクラス内のみで使える関数
	{
	cout << "親クラスprivate関数" << endl;
	};
 
 // protected部は継承クラスでも使える
 protected:
	int b;
	void TestProtected()
	{
	cout << "親クラスprotected関数" << endl;
	};	
 
 // public部はさらに外部(main)からでも使える(どこからでも使える)
 public:
	int c;
 
	// コンストラクタ
	Parent(){}
 
	// クラス内変数を引数付コンストラクタで初期化
	Parent(int inputA,int inputB,int inputC)
		:a(inputA),b(inputB),c(inputC){}
 
	void ShowParent()
	{
	TestPrivate();
	TestProtected();
	cout <<  "a = " << a << endl;
	cout <<  "b = " << b << endl;
	cout <<  "c = " << c << endl;
	}
 };
 
 // 派生クラス(Parentの継承クラス)
 class Child: public Parent// ←public継承
 {
 private:
	int d;
 public:
	int e;
 
        // クラス内変数をコンストラクタで初期化
        Child(int inputA,int inputB,int inputC,int inputD,int inputE)
	    :Parent(inputA,inputB,inputC),d(inputD),e(inputE){}
  
        void ShowChild()
        {
          //TestPrivate(); // 親クラスのprivateにはアクセス不可
          TestProtected(); // 親クラスがpublicかprotectedならばアクセス可能
          //cout <<  "a = " << a << endl; // 親クラスのprivateにはアクセス不可
          cout <<  "b = " << b << endl;   // 親クラスがpublicかprotectedならばアクセス可能
          cout <<  "c = " << c << endl;   // 親クラスがpublicかprotectedならばアクセス可能
          cout <<  "d = " << d << endl;
          cout <<  "e = " << e << endl;
	}
 };
 
 // main関数(クラスの外部)
 int main()
 {
 int inputA = 1,inputB = 2,inputC = 3,inputD = 4,inputE = 5;
 		
 Parent p(inputA,inputB,inputC);
 //cout << "a = " << p.a << endl;// privateは外部からアクセス不可
 //cout << "b = " << p.b << endl;// protectedは外部からアクセス不可
 cout << "c = "<< p.c << endl;	// publicなので外部からアクセス可能
 //p.TestPrivate();	 // privateは外部からアクセス不可
 //p.TestProtected(); // protectedは外部からアクセス不可
 p.ShowParent();		 // publicなので外部からアクセス可能
 
 cout << endl << endl;
 
 Child ch(inputA,inputB,inputC,inputD,inputE);
 //cout << "a = " << ch.a << endl;// privateは外部からアクセス不可
 //cout << "b = " << ch.b << endl;// protectedは外部からアクセス不可
 cout << "c = "<< ch.c << endl;	// 親クラスのpublicなので外部からアクセス可能
 //cout << "d = "<< ch.d << endl;// 子クラスのprivateなので外部からアクセス不可
 cout << "e = "<< ch.e << endl;	// 子クラスのpublicなので外部からアクセス可能
 //ch.TestPrivate();		 // privateは外部からアクセス不可 
 //ch.TestProtected();	 // protectedは外部からアクセス不可
 ch.ShowParent();	 // 親クラスのpublicなので外部からアクセス可能
 ch.ShowChild();	 // 子クラスのpublicなので外部からアクセス可能
 
 return 0;
 }

余力があったら
コメントアウトしてる各所をはずしてコンパイルしてみてください
アクセスできないというエラーメッセージがでてくるはずです
この辺の理由はコメントアウトの説明を見て
こうゆうものだと思ってください

直感としてはpublicはどこからでもアクセス可能
(実はprivate継承だけ例外ありだけどこれについては考えなくていい)
protectedは継承クラスでも使える
privateは自分のクラスの中だけしか使えない

と覚えておけばおk

さて、public継承とprotected継承の違いについて説明します
まず、public継承部分を

 class Child: public Parent// ←public継承

次のようにprotected継承にします

 class Child: protected Parent// ←protected継承

すると↓の部分でエラーがでると思います

 cout << "c = "<< ch.c << endl;	// 親クラスのpublicなので外部からアクセス可能
 ch.ShowParent();	 // 親クラスのpublicなので外部からアクセス可能

上の2行をコメントアウトすると
コンパイルは通ると思います
protectedな継承とは、親クラスのpublicなメンバに
外部からはアクセスできなくしているということです

privateな継承というものも存在しますが
継承の意味が薄れるのであまり使われることはありません
publicやprotectedで継承することがほとんどです


#vote((^ω^)わかったお[6],普通[0],。(`ω´#)。わかりにくぃぜぇえええええ[7])
|(^ω^)わかったお|6|
|普通|0|
|。(`ω´#)。わかりにくぃぜぇえええええ|7|



トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS