C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++のoverrideキーワード解説:仮想関数のオーバーライドを安全に行う方法


overrideキーワードとは?

本記事では、C++プログラミングにおける「override」キーワードの役割と基本的な使い方について解説します。

overrideキーワードは、基底クラス(親クラス)で定義された仮想関数を、派生クラス(子クラス)で同じシグネチャの関数によって再定義(オーバーライド)することを明示するための指定子です。C++11で導入されました。

オーバーライドが成立するためには、基底クラス側の関数がvirtual宣言されていることに加え、関数名・引数・const修飾などのシグネチャが完全に一致している必要があります。

コード例:オーバーライドのつもりが隠蔽になってしまうパターン

まずは、overrideを使わない場合によくあるミスを見てみましょう。次の例では、派生クラスでfunc(int a)を定義していますが、引数が異なるためオーバーライドにはならず、基底クラスのfunc()が隠蔽されてしまいます。

#include <iostream>
using namespace std;
class Base {
    public:
    // オーバーライド対象となる仮想関数
    virtual void func() {
        cout << "I am in base" << endl;
    }
};
class Derived : public Base {
    public:
    void func(int a) {
        cout << "I am in derived class" << endl;
    }
};
int main(){
    Derived d;
    d.func(6);
    return 0;
}

出力

I am in derived class

このコードは一見正常に動作しますが、実はBase::func()はオーバーライドされていません。引数の違いにより別の関数として扱われているだけで、意図しない動作の原因になりかねません。

overrideキーワードでミスを防ぐ

このような関数にoverrideを付けると、コンパイラが「基底クラスに対応する仮想関数が存在するか」を自動的にチェックしてくれるようになります。

class Derived : public Base {
    public:
    void func(int a) override {
        cout << "I am in derived class" << endl;
    }
};

この場合、基底クラスにはvoid func(int)という仮想関数は存在しないため、コンパイルエラーが発生します。つまり、「オーバーライドのつもりが失敗していた」というバグをコンパイル段階で検出できるのです。

正しいオーバーライドの書き方

class Derived : public Base {
    public:
    void func() override {
        cout << "I am in derived class" << endl;
    }
};

まとめ

overrideキーワードは必須ではありませんが、次のようなメリットがあります。

  • シグネチャの不一致によるオーバーライド漏れをコンパイル時に検出できる
  • 関数がオーバーライド用であることが明確になり、可読性が向上する
  • 基底クラスの仕様変更時にも、影響箇所を安全に把握できる

仮想関数を派生クラスで再定義する場合は、必ずoverrideを付ける習慣をつけておくとよいでしょう。

  1. C++でオブジェクト指向プログラミングを始めるには?基本概念をわかりやすく解説

    オブジェクト指向プログラミング(Object-Oriented Programming、OOP)は、「オブジェクト」という概念を土台としたプログラミング手法(パラダイム)です。オブジェクトは、属性(attribute)という形でデータを保持し、メソッド(method)という形で処理内容を備えています。 たとえば「人間」をオブジェクトとして捉えると、身長・性別・年齢といった属性を持ち、「移動する」「話す」などのメソッドを持つことになります。 オブジェクトとは オブジェクトは、オブジェクト指向プログラミングにおける基本単位です。データと、そのデータを操作する関数(処理)が、ひとつのまとまりとして束

  2. C++のfriendキーワードに相当するC#の機能とは?

    C#におけるfriendの概念C++におけるfriend関数(フレンド関数)は、クラスのスコープ外で定義される関数でありながら、そのクラスのすべてのprivateメンバーおよびprotectedメンバーにアクセスする権限を持つ特別な関数です。friend関数のプロトタイプ宣言はクラス定義内に記述されますが、friendはあくまでメンバー関数ではなく、クラス外部の存在である点に注意が必要です。friendとして指定できるのは、関数、関数テンプレート、メンバー関数のほか、クラスやクラステンプレートも可能です。クラスをfriendとして指定した場合、そのクラス全体とすべてのメンバーがフレンド関係とな