本文へスキップ
BecomeCoder

C++コース · 第11章 継承とポリモーフィズム ― 型を広げる · レッスン45

オーバーライド ― 子で振る舞いを上書きする

ブラウザで完結

導入

親から引き継いだメンバ関数を、子で「別の中身」に置き換えたいことがあります。これを「オーバーライド」と言います。まずは基本の書き方と、親の処理も呼ぶ方法を見ます。

説明

親と同じ名前・引数のメンバ関数を子で定義すると、子のオブジェクトではそちらが使われます。親の処理を土台に足したいときは 親クラス名::関数名() で親のものを呼べます。

#include <iostream>
#include <string>
using namespace std;

class Animal {
public:
    string name;
    Animal(string n) : name(n) {}
    void greet() { cout << name << " です" << endl; }
};

class Dog : public Animal {
public:
    Dog(string n) : Animal(n) {}
    void greet() {              // 親の greet を上書き
        Animal::greet();        // 親の処理も呼べる
        cout << "ワンと鳴きます" << endl;
    }
};

int main() {
    Dog d("ポチ");
    d.greet();   // ポチ です / ワンと鳴きます
    return 0;
}

ただし、この「名前で隠す」だけの上書きには落とし穴があります。親の型のポインタや参照から呼ぶと、親のほうが呼ばれてしまうのです。それを解決するのが次のレッスンの virtual です。

まとめ

親と同じ関数を子で定義すると上書きできます。親の処理は 親::関数() で呼べます。ただし「親の型を通して呼ぶと親が呼ばれる」問題があり、本当のポリモーフィズムには virtual が必要です。

実際に動かしてみよう

下のエディタにC++を書いて「コンパイル & 実行」を押すと、ブラウザ内で本物のC++コンパイラ(clang + libc++)がその場でコンパイルして実行し、出力が表示されます。std::string・vector・クラス・テンプレート・STL などモダンC++がそのまま動きます。本文の例を書き換えて試しながら進めましょう(初回だけコンパイラの読み込みに時間がかかります。以降はキャッシュされます。この回は標準入力(cin)は使わず、値はコードに直接書きます)。

C/C++ — ブラウザ内で本物のコンパイラで実行

ブラウザ内で本物のC/C++コンパイラ(clang + libc++ / WebAssembly)を動かします。構造体・malloc/free・std::string・vector・クラス・テンプレート・STL などがそのまま実行できます(初回のみコンパイラの読み込みに時間がかかります。以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。