純粋仮想関数について

純粋仮想関数のことがだんだんわからなくなってきたので、C++ランゲージクイックリファレンスがなぜかウチにあったので読んでみることにする。pp.191には

関数が純粋であると宣言されていても、関数の定義を提供することは可能である(ただし、クラス定義では提供できない)。純粋仮想関数の定義を利用すれば、プログラマにどの関数が純粋なのかを知らせなくても、派生クラスが継承した関数を呼び出せるようになる。

と書かれている。

で、テストケースを書いてみたのだがちょっと意味が分からず苦戦したけれども、ちょっと先に続くこの文を読んで理解した(関数名は書き換えている)。

vtest::test()は、純粋であるにもかかわらず、関数本文を持っている。派生クラスはvtest::testをオーバーライドしなければならないが、それを呼び出すこともでき、さまざまなtest関数の実装を統一することができる。つまり、testのどの実装も、基底クラスのtestを呼び出すことから始まる。vtestを直接継承するクラスは、間接的に継承するクラスのものとは別のtestを実装する必要がない。

要は、親クラスのvtest::testを直接呼び出すことはできないけれども、hoge::test()からなら呼び出せるらしいということだ。以下、テストケース

#include <iostream>
using namespace std;

class vtest{
public:
  vtest(){};
  virtual ~vtest();

  virtual void test() =0;
};

void vtest::test(){
  cout << "I'd be rather virtual." << endl;
} 
vtest::~vtest(){}

class hoge: public vtest{
public:

  hoge(){};
  ~hoge(){};
  void test(){  //これがないとvtest::test()はどこからも使えないようだ
	  vtest::test();
	  cout << "I'd not be rather virtual." <<endl; 
  };
};

int main(){
  hoge sample;
  sample.test();
}

vtestオブジェクトを宣言して、そこから直接vtest::test()を呼び出すことはできないというか、純粋仮想関数があるオブジェクトはどうやら宣言できないっぽいようなそんな感じだ。この辺り勉強不足ですねハイ。

C++ランゲージクイックリファレンス

C++ランゲージクイックリファレンス