【C++】基本クラスへのポインタで、派生クラスのオブジェクトを指す方法

目次

はじめに

C++の継承において、「is-a 関係」という重要な概念があります。これは、「車は乗り物の一種である」というように、子クラスが親クラスの一種である、という関係性を示すものです。

この is-a 関係があるため、C++では、親クラスを指すポインタを使って、子クラスのオブジェクトを指し示すことができます。これにより、親クラスの共通のインターフェースを通じて、子クラスのオブジェクトを統一的に扱うことが可能になります。

この記事では、基本クラスへのポインタが、基本クラスと派生クラスの両方のオブジェクトを指し示す様子を、RPGのキャラクターを例に解説します。


ポインタでオブジェクトを統一的に扱うサンプルコード

このコードは、Character(キャラクター)という親クラスと、それを継承した Player(プレイヤー)という子クラスを定義します。そして、Characterクラスへのポインタの配列 party を使い、そこにCharacterオブジェクトと Playerオブジェクトの両方を格納し、統一的に扱います。

完成コード

#include <iostream>
#include <string>

using namespace std;

// --- 親クラス(基本クラス) ---
class Character {
protected:
    string name;
    int hp;
public:
    Character(string n, int h) : name(n), hp(h) {}
    void showStatus() {
        cout << "名前: " << name << ", HP: " << hp << endl;
    }
};

// --- 子クラス(派生クラス) ---
class Player : public Character {
public:
    int level;
    Player(string n, int h, int l) : Character(n, h), level(l) {}
    // 親クラスのshowStatus()をオーバーライド
    void showStatus() {
        cout << "名前: " << name << ", HP: " << hp << ", Lv: " << level << endl;
    }
};

int main() {
    // 1. 基本クラスのポインタの配列を準備
    Character* party[2];
    
    // 2. 親クラスと子クラスのオブジェクトを作成
    Character boss("スライム", 200);
    Player hero("勇者", 150, 10);
    
    // 3. 配列にそれぞれのオブジェクトのアドレスを代入
    //    親クラスへのポインタに、親クラスのアドレスを代入
    party[0] = &boss;
    //    親クラスへのポインタに、子クラスのアドレスを代入
    party[1] = &hero;
    
    // 4. ループで全てのオブジェクトを統一的に扱う
    for(int i = 0; i < 2; i++) {
        party[i]->showStatus();
    }
    
    return 0;
}

実行結果

名前: スライム, HP: 200
名前: 勇者, HP: 150, Lv: 10

コードの解説

pCars[0] = &car1;pCars[1] = &rccar1;

ご提示のコードのこの部分が、親クラスへのポインタに、親クラスと子クラス両方のアドレスを代入している核心部分です。

サンプルコードでは、Character* party[2]; という「Character型を指すポインタの配列」に、Characterオブジェクトのアドレス (&boss) と、Playerオブジェクトのアドレス (&hero) の両方を代入しています。

これは、PlayerCharacter を継承しているため、「PlayerCharacter の一種である」という is-a 関係が成り立つからです。

for(int i = 0; i < 2; i++) { party[i]->showStatus(); }

このループが、このテクニックの真価を示しています。

  • party配列には、CharacterPlayerという異なる種類のオブジェクトが混在しています。
  • しかし、どちらも親クラスである Character の機能(showStatus())を共有しているため、party[i]->showStatus() という同じコードで、それぞれのオブジェクトに合わせた正しい showStatus() 関数が呼び出されています。

これにより、オブジェクトの種類を意識することなく、複数の異なるオブジェクトを統一的に扱えるようになります。


まとめ

今回は、基本クラスへのポインタが、派生クラスのオブジェクトも指し示せるという、オブジェクト指向の重要な性質を解説しました。

  • 基本クラスへのポインタ には、基本クラスのオブジェクト派生クラスのオブジェクト の両方のアドレスを代入できる。
  • これにより、複数のオブジェクトを一つのポインタの配列などで管理し、統一的なインターフェースで操作できる。

この仕組みは、オブジェクト指向における「多態性(ポリモーフィズム)」の基礎であり、柔軟で拡張性の高いプログラムを構築する上で不可欠なテクニックです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次