■C++を学ぼう!
「C++を学ぼう!」では、C++の初心者をターゲットにC++言語を体系的に学べるようにサイトを構築しています。
管理人もC++を学びながら作っていますので、分かり難い点などあればご指摘下さい。

▼スポンサードリンク
■メニュー

(C)あいねこの館

文章などの改変・利用は禁止します
継承

継承とは何か?
特定のクラスの内容を別のクラスに引き継ぎ、前のメンバーの変数や関数を流用し、更に 新しく足したり修正したりすることを継承といいます。
このように、似たようなクラスを作成するのに何度も同じクラスを宣言する必要がありません。

新しいクラス元になるクラスを基本クラスといい、基本クラスから継承されたクラスを派生クラスといいます。

継承される前のメンバーも、新しいクラスで宣言したメンバーで上書きすることが出来ます。

派生クラスの宣言方法は以下の通りです。
class 派生クラス名:基本クラス名{
・・・
};
派生クラス前のクラスが例えば以下の通りです。
class Test1{

private:

	//プライベートメンバー変数を設定する
	int time1;

public:

	//パブリックなメンバー変数を宣言する
	int num1;

	//パブリックなメンバー関数を設定する
	void show_time1();
};
派生クラス後のクラスが例えば以下の通りです。
class Test2 : Test1{

private:

	//プライベートメンバー変数を設定する
	int time2;

public:

	//パブリックなメンバー変数を宣言する
	int num2;

	//パブリックなメンバー関数を設定する
	void show_time2();
};
ここでTest1から継承するときには:で区切りますが、Test1をpublicで継承するのか、それとも privateで区切るのかを決めることが出来ます。
publicで区切れば、Test1の中身をTest2のインスタンスからTest1のpublicのメンバー変数・関数を利用することが出来ますが、 privateで宣言するとTest1で例えpublicでメンバー変数が宣言されていてもTest2のインスタンスからはTest1のメンバー変数を 利用することが出来ません。
しかし、Test2内のクラスからではTest1のpublicのメンバー変数・関数を利用することが出来ます。その内容を下記のプログラムで 表現しました。

#include <iostream>
#include <string>

using namespace std;

//クラスCarを設定する
class Test1{

private:

	//プライベートメンバー変数を設定する
	int time1;

public:

	//パブリックなメンバー変数を宣言する
	int num1;

	//パブリックなメンバー関数を設定する
	void show_time1();
};

//クラスTest1を基本クラスとして派生クラスTest2を宣言する
//publicを省略するとprivateになり、Test1の内容を外部から利用できなくなる
class Test2 : Test1{

private:

	//プライベートメンバー変数を設定する
	int time2;

public:

	//パブリックなメンバー変数を宣言する
	int num2;

	//パブリックなメンバー関数を設定する
	void show_time2();
};

//クラスTest1のメンバー関数time1の設定
void Test1::show_time1(){
	cout << "現在の時刻は10時です" << endl;
}

//クラスTest2のメンバー関数time1の設定
void Test2::show_time2(){
	cout << "現在の時刻は23時です" << endl;
	show_time1();
}

int main(){

	Test2 hoge;


	hoge.show_time2();

	//show_time1を利用するためにはTest1をpublicで継承しなければならない
	//hoge.show_time1();

	getchar();
}
実行結果は以下の通りです。
現在の時刻は23時です
現在の時刻は10時です
上記は、Test1をprivateで継承していますので、クラスTest2のインスタンスはTest1のメンバー変数を継承しても 直接show_time1等のTest1を利用することが出来ません。
しかし、Test2内の関数からではTest1のpublicのメンバー変数・関数を利用することが出来ます。

また、Test2内からTest1のprivateで宣言されている内容を利用したいことも生じます。
この為、protectedを利用すると、クラス外からは利用できませんが、クラスのメンバー関数からは利用できるようになります。
#include <iostream>
#include <string>

using namespace std;

//クラスCarを設定する
class Test1{

protected:

	//プライベートメンバー変数を設定する
	int time1;

public:

	//パブリックなメンバー変数を宣言する
	int num1;

	//パブリックなメンバー関数を設定する
	void show_time1();
};

//クラスTest1を基本クラスとして派生クラスTest2を宣言する
//publicを省略するとprivateになり、Test1の内容を外部から利用できなくなる
class Test2 : Test1{

private:

	//プライベートメンバー変数を設定する
	int time2;

public:

	//パブリックなメンバー変数を宣言する
	int num2;

	//パブリックなメンバー関数を設定する
	void show_time2();
};

//クラスTest1のメンバー関数time1の設定
void Test1::show_time1(){
	cout << "現在の時刻は10時です" << endl;
}

//クラスTest2のメンバー関数time1の設定
void Test2::show_time2(){
	cout << "現在の時刻は23時です" << endl;
	show_time1();
	time1 = 1;
	cout << "メンバー変数time1の値は" << time1 << "です。" <<endl;

}

int main(){

	Test2 hoge;


	hoge.show_time2();

	//show_time1を利用するためにはTest1をpublicで継承しなければならない
	//hoge.show_time1();

	getchar();
}
実行結果は以下の通りです。
現在の時刻は23時です
現在の時刻は10時です
メンバー変数time1の値は1です。
それでは、様々な型が出来ましたので纏めてみましょう。
修飾語内容
privateクラス外からは利用不可。
派生クラスからも利用不可。
自分のクラスのメンバー関数からは利用可能。
publicクラス外からも利用可能。
派生クラスからも利用可能。
自分のクラスのメンバー関数からは利用可能。
protectedクラス外からは利用不可。
private派生クラスからは利用不可能で、public派生クラスからでは利用可能。
自分のクラスのメンバー関数からは利用可能。

派生クラスがprivateの場合の権限は下記の通りです。
private派生privatepublicprotected
クラス外××
基本クラス内
派生クラス××

派生クラスがpublicの場合の権限は下記の通りです。
private派生privatepublicprotected
クラス外××
基本クラス内
派生クラス×
関数のオーバーライド
関数のオーバーライドとは、派生クラス内で基本クラスのメンバー関数を上書きすることが出来ます。

しかし、引数の型が基本クラスと異なると別のメンバー関数としてみなされます。

//下記は異なるメンバー関数となります
void func::test(int a){
	cout << "test1" << endl;
}

void func2::test(int a,int b){
	cout << "test2" << endl;
}

//下記はメンバー関数のオーバーライドとなっています
void func::test1(int a){
	cout << "test3" << endl;
}

void func2::test1(int a){
	cout << "test4" << endl;
}
関数のオーバーライドをしてしまった場合でも、継承したオブジェクトはオーバーライド前の関数を利用することが可能です。
例えば、クラスfunc1のオブジェクトhogeは、func1のtest1を利用したいときはhoge.test1(引数)を実行します。
クラスfunc2のオブジェクトhogehogeはhogehoge.test1(引数)となります。

また、クラスfunc2からでもfunc1のtest1を呼び出すことが出来ます。
その場合は、スコープ解決演算子を付けます。
//下記は異なるメンバー関数となります
void func::test(int a){
	cout << "test1" << endl;
}

void func2::test(int a,int b){
	func::test(int a);//funcの基本クラスを利用可能です。
	cout << "test2" << endl;
}
それでは実際にサンプルプログラムから見てみましょう!