GitHubで公開しているC++参考書に、以下のようなpull requestが送られてきた。

Pure virtual function by daisukekoba · Pull Request #153 · EzoeRyou/cpp-book

純粋virtual関数は、宣言を分ければ、定義も持てるそうだ。実際にまともなC++コンパイラーでコンパイルしてみると、たしかにその通りだ。

どうやら、私の規格の文面の解釈が間違っていたらしい。

C++の規格に曰く、

10.4 paragraph 2

A function declaration cannot provide both a pure-specifier and a definition.

ひとつの関数宣言はpure指定子と定義の両方を提供することができない。

これを読むと、以下のコードがエラーになることがわかる。

struct S
{
// エラー、pure-specifierと定義を両方持つ
    virtual void f() = 0 { }
} ;

しかし、私は「ひとつの」という部分を見落としていた。つまり、複数の関数宣言を使えば、両方とも持てるのだ。

struct S
{
// pure-specifier
    virtual void f() = 0 ;
} ;

// 定義
void S::f() { } 

規格の文面を正しく解釈すると、このコードは正しいはずで、実際に、既存のC++コンパイラーはこのコードを通す。

上記記事では引用した場所以降も有用な検討をしているが、ひとまずここまでを実験してみた。

header.h

class C{

  public:

  void Fx(void) = 0;

};

class D : public C{

  public:
    void Fx(void);
};

main.cpp

#include <iostream>
using namespace std;

void C :: Fx(void){ cout << "C :: Fx" << endl; }
void D :: Fx(void){
  C :: Fx();
  cout << "D :: Fx" << endl;
}

int main(void){

  D d;
  d.Fx();

  return 0;
}

宣言と定義を別にしたら純粋仮想関数でも呼び出して実行できる。

インターフェイスがもつメンバ変数を初期化する際に便利かも。