Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

はじめに

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にて

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした