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

# はじめに

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

# 問題

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

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

```cpp: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:
>
>```cpp
>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``指定子は仮想関数につけるものです。もう一度コードを見ると

```cpp: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``

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

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

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

# 結論

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

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

```cpp: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
にツッコミを入れようと規格書を読んでいた。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">struct B {<br>virtual void f(int);<br>};<br>struct D : B {<br>void f(int) override;<br>};<br><br>virtualついてないメンバー関数にoverride指定つけるのって合法なの？</p>&mdash; yumetodo-C++erだけど化学科 (@yumetodo) <a href="https://twitter.com/yumetodo/status/791647990440079364">2016年10月27日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/yumetodo">@yumetodo</a> 基底クラスでvirtualならシグネチャーが同一の関数は暗黙的にvirtualなので合法</p>&mdash; 白山風露 (@kazatsuyu) <a href="https://twitter.com/kazatsuyu/status/791653436471123968">2016年10月27日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">&gt;基底クラスでvirtualならシグネチャーが同一の関数は暗黙的にvirtual<br><br>(つд⊂)ｺﾞｼｺﾞｼ<br><br>&gt;暗黙的にvirtual<br><br>・・・！？なにそれ！おどろ木ももの木さんしょの木！ <a href="https://t.co/SM2REc7Muc">https://t.co/SM2REc7Muc</a></p>&mdash; yumetodo-C++erだけど化学科 (@yumetodo) <a href="https://twitter.com/yumetodo/status/791654350623866880">2016年10月27日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">本当に <a href="https://twitter.com/yumetodo">@yumetodo</a> 氏は継承には弱いな <a href="https://t.co/qT8qptPOFD">https://t.co/qT8qptPOFD</a></p>&mdash; 白山風露 (@kazatsuyu) <a href="https://twitter.com/kazatsuyu/status/791655135021641728">2016年10月27日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">継承なんて大嫌いだーーーーー！！！！ <a href="https://t.co/mu3tBaSQlM">https://t.co/mu3tBaSQlM</a></p>&mdash; yumetodo-C++erだけど化学科 (@yumetodo) <a href="https://twitter.com/yumetodo/status/791655643002175488">2016年10月27日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">規格書読みに行ったら§ 10.3の1と3に本当に書いてあった。 <a href="https://t.co/mu3tBaSQlM">https://t.co/mu3tBaSQlM</a></p>&mdash; yumetodo-C++erだけど化学科 (@yumetodo) <a href="https://twitter.com/yumetodo/status/791655747830452226">2016年10月27日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">つーか一度見たはずのcpprefjpにもきっちり書いてあったorz<a href="https://t.co/G4C9vag2JK">https://t.co/G4C9vag2JK</a><br>注意力散漫だった <a href="https://t.co/SM2REc7Muc">https://t.co/SM2REc7Muc</a></p>&mdash; yumetodo-C++erだけど化学科 (@yumetodo) <a href="https://twitter.com/yumetodo/status/791656561940713472">2016年10月27日</a></blockquote>

C++の会Slackにて

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