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を付ける習慣をつけておくとよいでしょう。
-
C++でオブジェクト指向プログラミングを始めるには?基本概念をわかりやすく解説
オブジェクト指向プログラミング(Object-Oriented Programming、OOP)は、「オブジェクト」という概念を土台としたプログラミング手法(パラダイム)です。オブジェクトは、属性(attribute)という形でデータを保持し、メソッド(method)という形で処理内容を備えています。 たとえば「人間」をオブジェクトとして捉えると、身長・性別・年齢といった属性を持ち、「移動する」「話す」などのメソッドを持つことになります。 オブジェクトとは オブジェクトは、オブジェクト指向プログラミングにおける基本単位です。データと、そのデータを操作する関数(処理)が、ひとつのまとまりとして束
-
C++のfriendキーワードに相当するC#の機能とは?
C#におけるfriendの概念C++におけるfriend関数(フレンド関数)は、クラスのスコープ外で定義される関数でありながら、そのクラスのすべてのprivateメンバーおよびprotectedメンバーにアクセスする権限を持つ特別な関数です。friend関数のプロトタイプ宣言はクラス定義内に記述されますが、friendはあくまでメンバー関数ではなく、クラス外部の存在である点に注意が必要です。friendとして指定できるのは、関数、関数テンプレート、メンバー関数のほか、クラスやクラステンプレートも可能です。クラスをfriendとして指定した場合、そのクラス全体とすべてのメンバーがフレンド関係とな