🦔

virtual修飾子はオーバーライドしたメソッドに付ける必要はない

に公開

概要

C++にはvirtual修飾子というのがある。
このvirtual修飾子が基底クラスのメソッドに付いていれば仮想関数として扱われ、基底クラスのポインター経由で派生クラスのメソッドを実行することができる。
このvirtual修飾子だが、派生クラスでオーバーライドしたメソッドに対しては付ける必要があるかどうか分からなかったため検証した。

結論

virtual修飾子はオーバーライドしたメソッドに付ける必要はない。

詳細

以下のようにコードを書いて検証した。

class Base
{
public:
    virtual void Run() { std::cout << "Base Run" << std::endl; }
};

class Hoge : public Base
{
public:
    void Run() { std::cout << "Hoge Run" << std::endl; }
};

class Fuga : public Hoge
{
public:
    void Run() { std::cout << "Fuga Run" << std::endl; }
};

int main()
{
    Base* p1 = new Hoge();
    p1->Run(); // "Hoge Run"
    delete p1;

    Hoge* p2 = new Fuga();
    p2->Run(); // "Fuga Run"
    delete p2;

    return 0;
}

Baseクラスにはvirtual修飾子が付いた仮想関数のRunメソッドが定義されている。
そのため、Hoge型のポインタをBase型のポインタに代入しRunメソッドを実行すると、当然HogeクラスのRunメソッドが呼び出される。

では、Fuga型のポインタをHoge型のポインタに代入しRunメソッドを実行した場合はどうか。
HogeクラスのRunメソッドにはvirtual修飾子が付いていないが、FugaクラスのRunメソッドが呼び出された。
どうやら基底のBaseクラスのRunメソッドに付いているので仮想関数として扱ってくれる模様。

overrideしたメソッドにはvirtual修飾子は不要というのが分かった。

Discussion