C++勉強日記(2022/03/12):基礎3、継承
継承:
あるクラスの性質を受け継いだ新しいクラスを作る。
基本となるクラスの性質を受け継ぎ、独自の拡張をすることをオブジェクト指向では、継承と呼ぶ。
継承元となるクラスのことを親クラス、スーパークラス、基底クラスと呼ぶ。
親クラスを継承し、独自の機能を実装したクラスのことを子クラス、サブクラス、派生クラスという。
継承の方法:
code:c++
class 子クラス名:public親クラス名
table:クラス
クラス名 親クラス プログラム
継承元 Oya - oya.h、oya.cpp
継承先 Ko Oya ko.h、ko.cpp
例:
親クラスの作成
code:c++
//oya.hの作成
//親クラスの作成
class Oya{
public:
//コンストラクタ
Oya();
//デストラクタ
virtual ~Oya();
//関数oyaSetを宣言
//数値を書き込む関数
void oyaSet(int set);
//関数OyaBを宣言
//数値を読み込む関数
int oyaGet();
//関数oyaIndiを宣言
//計算及び表示する関数
void oyaIndi(int num);
private:
//変数の宣言
int oya_set;
int oya_calc;
};
code:c++
//oya.cppの作成
using namespace std;
//コンストラクタ
//親クラスの変数を初期化
Oya::Oya():oya_set(0),oya_calc(0){
cout<<"親クラス(Oya)のインスタンス生成"<<endl;
}
Oya::~Oya(){
cout<<"Oyaクラスのデストラクタ"<<endl<<endl;
}
//セッター (数値の書き込みを行う)関数の作成
void Oya::oyaSet(int set){
oya_set = set;
}
//ゲッター(oyaSetに書き込みした数値を呼び出す)関数の作成
int Oya::oyaGet(){
return oya_set;
}
//計算及び表示する関数
void Oya::oyaIndi(int num){
cout<<"Oya::oyaSetに代入した数値:"<<oya_set<<endl;
cout<<"oyaIndiに入力した数値*oyaSetに入力した数値:"<<oya_set*num<<endl;
//計算
oya_set = oya_set*num;
}
code:c++
//koクラスのヘッダ作成
//ko.h作成
//oyaクラスのインクルード
//子クラスの作成
class Ko:public Oya {
public:
//コンストラクタ
Ko();
//デストラクタ
~Ko();
//関数の作成
//数値を表示する関数
void ko_A();
private:
//表示用変数
int ko_num;
};
code:c++
//ko.cppの作成
using namespace std;
//コンストラクタ
Ko::Ko():ko_num(20){
cout<<"Koクラスのインスタンス生成"<<endl;
}
//デストラクタ
Ko::~Ko(){
cout <<"Koクラスのデストラクタ"<<endl;
}
//数値を表示する関数の作成
void Ko::ko_A(){
cout<< "ko_numの値:"<<ko_num<<endl;
}
code:c++
//main.cppの作成
//プログラム内容:Oyaクラス、Koクラスを作成し、動作を確認する。
//Oyaクラスで作成した関数をKoクラスで扱い、結果を表示する。
//Koクラスで作成した関数を実行する。
using namespace std;
int main(int argc,char** argv){
cout<<"--Oyaクラスの処理--"<<endl;
//Oyaクラスのインスタンスの生成
Oya* pOya = new Oya();
//数値を代入
pOya -> oyaSet(10);
//計算結果の表示
pOya -> oyaIndi(20);
//代入した値の表示
cout<<"Oyaクラスの総数:"<<pOya ->oyaGet()<<endl;
//Oyaクラスのインスタンスの削除
delete pOya;
//Koクラスの動作
cout<<"--Koクラスの処理--"<<endl;
Ko* pKo = new Ko(); //Koクラスのインスタンス作成
//Koクラスに数値を代入
pKo -> oyaSet(100);
//Koクラスの計算結果の表示
pKo -> oyaIndi(200);
//Koクラスの代入値を表示
cout<<"Koクラスの総数:"<<pKo -> oyaGet()<<endl;
//Koクラスで生成したko_numの数値の初期値
pKo -> ko_A();
delete pKo;
return 0;
}
利用できるメンバの比較
table:利用できるメンバ比較
メンバ関数名(public) Oyaクラスで利用可能 Koクラスで利用可能
oyaSet 〇 〇
oyaGet 〇 〇
oyaIndi 〇 〇
ko_A × 〇
メンバ変数
table:利用できるメンバ変数
メンバ変数名(private) Oyaクラスで利用可能 Koクラスで利用可能
oya_set 〇 ×
oya_calc 〇 ×
ko_num × 〇
確認事項:
子クラスのインスタンスが生成される場合、子クラスのインスタンスが生成される前に、親クラスのインスタンスが生成される。
子クラスのインスタンスが消去される場合に、子クラスのインスタンス消去後、親クラスのインスタンスも消去される。
virtual修飾子については、後ほど説明
protectedメンバ
protectedメンバの説明
子クラスから親クラスのprotectedにアクセスできる。
クラス外からは、親クラスのprotectedにアクセス出来ない。
アクセス指定子の種類:
table:アクセス指定子
アクセス指定子 意味
public 全ての範囲からアクセス可能
private 同一クラス又は同一インスタンス内でのみアクセス可能
protected 同一クラス又は同一インスタンス内もしくは、サブクラス及びそのインスタンス内でのみアクセス可能
〇:アクセス出来る。(変数や関数を使用できる)
×:アクセス出来ない。(変数や関数を使用できない。)
table:指定子のアクセス表
親クラス
public private protected
親クラス 〇 〇 〇
子クラス 〇 × 〇
クラス外 〇 × ×
ポリモーリズム
同じ名前の関数を複数定義して、状況に応じて呼び出す関数を使い分ける仕組みのこと。
C++では、
ポリモーリズムを表現する方法として下記2つがある。
オーバーロード
同一クラス内でも「引数の型」もしくは「引数の数」を変えて、同じ名前の関数を複数定義出来る。
オーバーライド(override)
親クラスと子クラスに同じ名前、同じ戻り値、同じ引数を取るメンバ関数が存在する場合、子クラスを使用する場合、子クラスのメンバ関数が実行される。(子クラスのメンバ関数は、親クラスのメンバ関数をオーバーライドするという)
virtual修飾子と仮想関数
仮想関数:
C++では、継承元のクラス(親クラス)から継承先のクラス(子クラス)のメンバ関数を呼び出せない。
親クラスで、子クラスのメンバ関数を呼び出す方法が、仮想関数。
仮想関数を作成するのに、virtual修飾子を使用する。
例:
code:c++
//oya.hの作成
//親クラスの作成
class Oya{
public:
//関数oyaSingを宣言
//「歌う」を表示する
virtual void oyaSing();
//関数OyaRunを宣言
//「走る」を表示する。
void oyaRun();
};
code:C++
//oya.cppの作成
using namespace std;
//関数の作成
void Oya::oyaSing(){
cout<<"歌う(親)"<<endl;
}
void Oya::oyaRun(){
cout<<"走る(親)"<<endl;
}
code:c++
//子クラスのヘッダ
//ko.h作成
//oyaクラスのインクルード
//子クラスの作成
class Ko:public Oya {
public:
//関数oyaSingを宣言
//「歌う」を表示する。
void oyaSing();
//関数oyaRunを宣言
//「走る」を表示する。
void oyaRun();
void koJump();
};
code:c++
//ko.cppファイルの作成
using namespace std;
//関数の作成
void Ko::oyaSing(){
cout<< "歌う(子)"<<endl;
}
void Ko::oyaRun(){
cout<< "走る(子)"<<endl;
}
void Ko::koJump(){
cout<<"ジャンプ(子)"<<endl;
}
code:c++
//メイン.cppの作成
using namespace std;
int main(int argc,char** argv){
//親クラスのインスタンス作成
Oya* pOya;
Oya* pKo;
pOya=new Oya();
pKo=new Ko();
//子クラスのインスタンス作成
Ko* pKo2 = new Ko();
//親クラス関数実行
//virtual修飾子あり
pOya->oyaSing();
pKo->oyaSing();
//pKo->koJump(); //コメントを外すとエラー
//virtual修飾子なし
pOya->oyaRun();
pKo->oyaRun();
//子クラスの関数実行
pKo2->oyaSing();
pKo2->oyaRun();
pKo2->koJump();
return 0;
}
C++の基礎学習は、今回のポリフォーリズムで終わりになります。
次回からは、C++ Builderの使い方、C++ Builderでアプリを作りながらの学習になります。
ここまでの内容は「」の5日目までの内容を、自分が必要な部分を学習してきました。
その為、「」では、もっと詳しい内容が記載してあります。
また、6日目、7日目の内容には
テンプレートとSTL(スタンダードテンポラリライブラリ)について
C++で用意されているライブラリの使い方(vectorやlistなど)
テンsプレートとは
覚えておきたい基礎知識
参照渡し
クラスの相互参照
stringクラスの応用
インターフェースについて
オーバーロードについて
などの、C++を扱う上で、重要な項目があります。
もしもC++を学習したい方が居ましたら、是非自分の手で取って、学習することをお勧めします。
ここで、6日目、7日目の内容に振れないのは、下記3点の理由からです。
誤った情報があるかもしれないので、自分で書籍を買って、しっかり確認、学習してほしい。
自分が必要な知識が5日目までで十分で、C++ Builderを先にやる必要がある。
一通り確認しているので、必要になったら、再度まとめるつもり。
以上、ここまで読んでくださりありがとうございました。