LoginSignup
16
9

More than 5 years have passed since last update.

そのoverride指定は合法ですか?違法ですか?

Last updated at Posted at 2016-10-27

はじめに

C++11では、文脈依存キーワードfinaloverrideが追加されました。ここでoverrideについて見てみます。

問題

次の2つのコードは合法でしょうか?違法でしょうか?

1つ目
struct B {
void f(int);
};
struct D : B {
void f(int) override;//合法?違法?
};
2つ目
struct B {
virtual void f(int);
};
struct D : B {
void f(int) override;//合法?違法?
};

規格書を読みつつ答えよう

1つめ

違法です

根拠を見てみましょう。

10.3 Virtual functions [class.virtual]

5 If a virtual function is marked with the virt-specifier override and does not override a member function of
a base class, the program is ill-formed. [ Example:

struct B {
virtual void f(int);
};
struct D : B {
virtual void f(long) override; // error: wrong signature overriding B::f
virtual void f(int) override; // OK
};

—end example ]

override指定子は仮想関数につけるものです。もう一度コードを見ると

1つ目
struct B {
void f(int);
};
struct D : B {
void f(int) override;//合法?違法?
};

D::fは仮想関数ではありません。よってoverride指定子はつけられません。

2つめ

合法です

根拠を見てみましょう。

10.3 Virtual functions [class.virtual]

2 If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf

もう一度コードを見てみましょう

2つ目
struct B {
virtual void f(int);
};
struct D : B {
void f(int) override;//合法?違法?
};

D::f一見仮想関数ではないように見えますが、基底クラスB同じシグネチャー(名前や引数とか)の仮想メンバー関数B::fがあります。なのでD::fは仮想関数となり、同じシグネチャーなのでオーバーライドしているため、override指定子をつけることができます。

結論

struct B {
virtual void f(int);
};
struct D : B {
void f(int) override;//これは仮想関数
};

ところでcpprefjpをみてみようか

cpprefjpの例より抜粋
//基底クラス
class base {
  virtual void func_final() final;
  virtual void func_virt();
  virtual void func_virt_int(int a);
  void func_non_virt();
};

//派生クラス
class derived : public base {
  //NG, final メンバ関数はオーバーライドできない
  void func_final();

  //OK, オーバーライドできている
  void func_virt() override;

  //NG, 引数の個数、型が違っており、オーバーライドできてない
  void func_virt_int(short a) override;

  //NG, 基底クラスの func_non_virt() は仮想関数では無いので、オーバーライドできていない
  void func_non_virt() override;
};

がっつり書いてあったぞい。

経緯

最初は
http://qiita.com/knknkn1162/items/9a65ca65b558f31121f0
にツッコミを入れようと規格書を読んでいた。

C++の会Slackにて

そうですね。補足すると、当然ながらデストラクタも同様です。

16
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
9