Version 17.01
クラスの継承
「この章では、前回までのクラスの使い方を踏まえて、さらに深い使い方に
ついて説明します」
『つまり、これまでの応用編ってこと?』
「ううん、確かにこれまでの知識は使うんだけど、それとは別に新しく説明
することの方が多いかな」
『新しい説明……』
「そう、特に【オブジェクト指向】っていう新しい考え方について説明しま
す」
『オブジェクト指向ってよく聞くよね』
「今のプログラミングでは必須だね。 C++ では言語の仕様上本格的に使う
ことは少ないんだけど」
『え、そうなの?』
「そのへんはこれから少しずつ説明していくから。まずは、その一番重要な
機能、【継承】について説明します」
『けいしょう……前にちょっとだけやったね』
「 Version 3.1 ( No.026 ) で説明したけど、もう一度ちゃんと説明する
ね。継承というのは【あるクラスのメンバ変数やメンバ関数を受け継いだ
クラスを作ることができる】という機能のことです」
『あるクラスの機能を受け継ぐ……』
「そう、たとえばこんな感じに」
// Data.h
// CData クラス。
class CData
{
public:
// データ格納用メンバ変数。
int m_iData;
// 出力用メンバ関数。
void Output();
};
// CData クラスの派生クラス。
class CDerivedData : public CData
{
};
// Data.cpp
#include <Windows.h>
#include <stdio.h>
#include "Data.h"
// 出力用メンバ関数。
void CData::Output()
{
// m_iData を出力します。
char pch[256];
sprintf( pch, "%d\n", m_iData );
OutputDebugString( pch );
// 100
}
「この例では、 CData クラスから継承した CDerivedData クラスを作って
います」
// →これがそう←
class CDerivedData : public CData
{
};
「こんな感じに、クラスの右側に【: public クラス名】と書くと、この
【クラス名】のメンバ変数とメンバ関数を受け継ぐことができます」
『ってことは、この CDerivedData ってクラス、中身何もないけど CData
クラスと同じ事ができるってこと?』
「そういうこと。使用例はこんな感じ」
// Main.cpp
#include <Windows.h>
#include <stdio.h>
#include "Data.h"
int WINAPI WinMain
( HINSTANCE p_hInstance
, HINSTANCE p_hPrevInstance
, LPSTR p_pchCmdLine
, int p_iCmdShow
)
{
// CData クラスを使用します。
CData cData;
cData.m_iData = 100;
cData.Output();
// 100
// CDerivedData クラスを使用します。
CDerivedData cDerivedData;
cDerivedData.m_iData = 200;
cDerivedData.Output();
// 200
return 0;
}
『うわ! ホントだ、 CData クラスと CDerivedData が同じように使えて
る! CDerivedData クラスって中身空っぽなのに!』
「 CDerivedData クラスは CData クラスから継承しているから、
CData クラスが持つ m_iData メンバ変数も Output() メンバ関数も使うこ
とができるんです」
『はー……』
「ここで、用語のまとめと、図の書き方について説明します」
『用語と図……図?』
「そう、図。まずはクラスを図で書くときの説明からしようか。クラスを
図で書くときには、以下のように書きます」
┌────────┐
│クラス名 │
├────────┤
│メンバ変数 │
├────────┤
│メンバ関数 │
└────────┘
「たとえばこの CData クラスを図に書くときには、以下のように書きます」
┌────────┐
│CData │
├────────┤
│m_iData │
├────────┤
│Output() │
└────────┘
『なんだ、簡単じゃん』
「あと、継承関係がある場合には、以下のように書きます」
┌────────┐
│CData │
├────────┤
│m_iData │
├────────┤
│Output() │
└────────┘
△
│
┌────────┐
│CDerivedData │
├────────┤
│ │
├────────┤
│ │
└────────┘
『三角矢印ってこと?』
「そう、こんな感じで継承元と継承先クラスを書きます。そして、今言った
継承元と継承先だけど、実際には以下の用語を使用します」
┌────────┐
│CData │基本クラス、基底クラス、親クラス、スーパークラス
├────────┤
│m_iData │
├────────┤
│Output() │
└────────┘
△
│
┌────────┐
│CDerivedData │派生クラス、子クラス、サブクラス
├────────┤
│ │
├────────┤
│ │
└────────┘
『って、用語多すぎ!』
「基本的には以下の対のうちどれかを使う感じかな」
基本クラス 基底クラス 親クラス スーパークラス
△ △ △ △
│ │ │ │
派生クラス 派生クラス 子クラス サブクラス
「本によってどれを使うか違うから注意してね。僕はこの講座では
基本クラス
△
│
派生クラス
「のペアを使用します」
『はーい』
「というわけで次回に続く!」
/*
Preview Next Story!
*/
『いつも思うんだけど、最初は簡単だよね』
「そうだよ、簡単だから」
『それにいつも騙されるんだよねー』
「なにを人聞きの悪い」
『というわけで次回』
< Version 17.02 派生クラスでのメンバの追加 >
「につづく!」
『ひとつずつ進めて行くに従って難しくなるってゆーか』
「ひとつひとつは簡単だけど、まとめると大変ってそれだけの話」
『ホントにそれだけー?』