C++でオーバーライドを実現する方法


C++でオーバーライドを実現するためには上書き対象の関数にvirtual指定子を指定する必要があります。なお、virtual指定子によってオーバライド可能になった関数は仮想関数と呼ばれます。

struct Animal {
   void say() { puts(makeSound()); }
   virtual const char* makeSound() { return "----"; };
};

struct Cat : Animal {
   const char* makeSound() override { return "にゃー!"; }
};
struct Dog : Animal {
   // const char* makeSound() override { return "ワン!"; }
};

Cat().say(); // "にゃー!"
Dog().say(); // "----"
ちなみに、オーバライド時、派生クラス側の関数ではvirtualキーワードの省略が可能になります。後に説明するoverrideキーワードの指定を必須にする代わりに、virtualキーワードの省略を容認するのがオススメのコーディングスタイルです。ただし、闇雲に省略しようとはせず、対象の派生クラスが更に別のクラスから継承されるようなケースがある場合はきちんと明示するのがベストです。

override指定子

C++11以降のC++ではオーバーライド時にoverride指定子を明示することが出来ます。 overrideを指定した関数が非仮想関数や未定義関数だった場合にはコンパイルエラーが発生します。

struct Cat : Animal {
   // Error: Only virtual member functions can be marked 'override'
   const char* MIKESOUND() override { return "にゃー!"; }
};

final指定子

final指定子はオーバーライドを禁止するためのキーワードです。 例えば「サブクラス(Cat)のサブクラス(Nyan)にはオーバーライドを許可したくない」といったケースで利用されます。

struct Cat : Animal {
   // Catのサブクラスにはオーバーライドを許可しないことを明示する
   const char* makeSound() final { return "にゃー!"; }
};
struct Nyan : Cat {
   // 親クラスでfinalが指定されているためオーバーライド出来ない
   // Error: Declaration of 'makeSound' overrides a 'final' function
   const char* makeSound() override { return "うー"; }
};

広告