💭

override指定子をオーバーライドするメンバ関数につける理由

2022/10/24に公開

概要

C++にはoverride指定子というものがある。
override指定子というのは基底クラスのメンバ関数をオーバーライドした際、そのメンバ関数に付けるキーワードである。
override指定子は付けても付けなくても関数コール等の動作自体は変わらない。
ではなぜ必要なのか?

必要な理由

override指定子を付けたメンバが基底クラスでvirtual定義されていない場合、コンパイル時にエラーにしてくれるため。(実装ミスに気付ける)

詳細

例えば以下のような実装の場合、override指定子をFuncのメンバ関数に付けなくても正しく実装できてしまい正しく動作する。

class Base
{
public:
    Base() = default;
    virtual ~Base() = default;
    virtual void Func(int a) {;}
};

class Hoge : Base
{
public:
    Hoge() = default;
    virtual ~Hoge() = default;
    virtual void Func(int a) {;} // 派生クラスでoverrideするメンバ関数
};

int main()
{
    Hoge* p_hoge = new Hoge();
    Base* p_base = (Base*)p_hoge;
    p_base->Func(0); // HogeクラスのFuncがコールされる
    delete p_hoge;
    return 0;
}

しかし、以下のように派生クラスで基底クラスのFuncメンバ関数をオーバーライドするつもりが、
引数を間違って実装してしまったとする。その場合、コンパイラが別のメンバ関数が定義されたと扱うのでコンパイルも通ってしまう。そのため動かすまで気づくことができない。

override指定子を付けておけばコンパイルエラーで気づくことができるので、ミスに気づきやすい。
ということで派生クラスでオーバーライドするメンバ関数は必ずoverride指定子を付けるべき。

Discussion