導入
「同じ操作でも、実際の型に応じて違う振る舞いをする」――これがポリモーフィズム(多態性)です。C++ では、親の関数に virtual を付けることで実現します。オブジェクト指向のいちばんの見せ場です。
説明
親の関数に virtual を付けると、親の型のポインタ・参照から呼んでも「実際のオブジェクトの型」の関数が呼ばれます。子側には override を付けて上書きだと明示します。
flowchart TB ptr["Animal* p(親の型のポインタ)"] ptr -->|"実体が Dog なら"| d["Dog::speak() が呼ばれる"] ptr -->|"実体が Cat なら"| c["Cat::speak() が呼ばれる"]
#include <iostream>
#include <vector>
using namespace std;
class Animal {
public:
virtual void speak() { // virtual を付ける
cout << "……" << endl;
}
};
class Dog : public Animal {
public:
void speak() override { // override で上書きを明示
cout << "ワン!" << endl;
}
};
class Cat : public Animal {
public:
void speak() override {
cout << "ニャー" << endl;
}
};
int main() {
vector<Animal*> zoo = { new Dog(), new Cat(), new Dog() };
for (Animal* a : zoo) {
a->speak(); // 実際の型に応じて切り替わる(ワン!/ ニャー / ワン!)
}
for (Animal* a : zoo) delete a; // 後片付け
return 0;
}
もし virtual を付けないと、Animal* から呼んだときはすべて Animal::speak()(……)になってしまいます。virtual があるからこそ、実際の型で切り替わるのです。
まとめ
親の関数に virtual、子に override を付けると、親の型のポインタ・参照から呼んでも実際の型の関数が動きます。これがポリモーフィズムで、異なる型を同じインターフェースでまとめて扱えるようになります。