14_継承と派生クラス

はじめに

C++では「既存のクラスを元に、少し機能を変えた新しいクラスを作る」ことができます。これを「継承(けいしょう)」と呼びます。

継承の基本

基本の書き方は以下のとおりです:

class 子クラス名 : public 親クラス名 {
    // 追加のメンバやメソッドを定義
};
ポイント
子クラス(派生クラス)は、親クラス(基底クラス)のメンバ変数やメソッドをそのまま受け継ぎます。子クラスは自分だけの機能も追加できます。

例:ゲーム内キャラクターの継承

// 14_enemy_inheritance.cpp
#include <iostream>
using namespace std;

class GameObject {
public:
    string name;

    void showName() {
        cout << "オブジェクト名: " << name << endl;
    }
};

class Enemy : public GameObject {
public:
    int hp;

    void attack() {
        cout << name << " が攻撃してきた!" << endl;
    }
};

int main() {
    Enemy slime;
    slime.name = "スライム";
    slime.hp = 30;

    slime.showName();   // 親クラスのメソッド
    slime.attack();     // 子クラス独自のメソッド

    return 0;
}

解説

理解度チェック

問題14-1

次のコードを実行したとき、出力される内容はどれですか?

#include <iostream>
using namespace std;

class GameObject {
public:
    string name;

    void show() {
        cout << "名前:" << name << endl;
    }
};

class Boss : public GameObject {
public:
    void taunt() {
        cout << name << "「我を倒せる者などおらぬ!」" << endl;
    }
};

int main() {
    Boss b;
    b.name = "魔王";
    b.show();
    b.taunt();
    return 0;
}
解説を表示 正解:ア
BossGameObject を継承しているので、name(public)と show() をそのまま使えます。b.show() → "名前:魔王"、b.taunt() → "魔王「我を倒せる者などおらぬ!」" の順で出力されます。

問題14-2

継承の説明として正しいものはどれですか?

解説を表示 正解:イ
public 継承では、親クラスの public メンバはそのまま子クラスでも public として使えます。private メンバは子クラスからも直接アクセスできません(protected を使う必要があります)。

問題14-3

次のコードはコンパイルできますか?また実行結果はどれですか?

#include <iostream>
using namespace std;

class Animal {
public:
    string name;
    void speak() { cout << name << " が鳴いた" << endl; }
};

class Dog : public Animal {
public:
    void fetch() { cout << name << " がボールを取ってきた" << endl; }
};

int main() {
    Dog d;
    d.name = "ポチ";
    d.speak();
    d.fetch();
    return 0;
}
解説を表示 正解:ウ
DogAnimal を継承しているので namespeak() が使えます。d.name = "ポチ" でセットし、speak() → "ポチ が鳴いた"、fetch() → "ポチ がボールを取ってきた" の順で出力されます。

問題14-4

class B : public A の書き方で、B(子クラス)が使えるのはどれですか?

解説を表示 正解:イ
public 継承では、子クラスから親クラスの public および protected メンバにアクセスできます。private メンバは子クラスからも直接アクセス不可です。もちろん子クラス自身が定義したメンバも使えます。

コーディング演習

演習1:基本コードを動かす

14_01_inherit.cpp を作成し、次のコードを入力して実行しましょう。
// main.cpp
#include <iostream>
using namespace std;

class GameObject {
public:
    string name;

    void show() {
        cout << "名前:" << name << endl;
    }
};

class Enemy : public GameObject {
public:
    int hp;

    void attack() {
        cout << name << " が攻撃した!" << endl;
    }
};

int main() {
    Enemy goblin;
    goblin.name = "ゴブリン";
    goblin.hp = 50;

    goblin.show();
    goblin.attack();

    return 0;
}

演習2:コードを改造する

14_01_Inheritmain.cpp をコピーして 14_02_InheritMod に貼り付け、次の変更を加えてみましょう:
override キーワードについて:
override は「この関数は親クラスの関数を上書きしている」ということをコンパイラに伝えるキーワードです。 書かなくても動作しますが、書くことでスペルミスや引数の不一致を検出できます。 詳しくは 19章(オーバーライドとポリモーフィズム) で扱います。

まとめ