ISO C ++標準では、純粋仮想ではないクラスのすべての仮想メソッドを定義する必要があると規定されています。
簡単に言えば、ルールは次のとおりです。
、派生クラスが基本クラスの仮想メソッドをオーバーライドする場合、定義も提供する必要があります。そうでない場合は、基本クラスがそのメソッドの定義を提供する必要があります。
コード例の上記のルールに従って、virtual void bar();
Baseクラスに定義が必要です。
参照:
C ++ 03標準:10.3仮想関数[class.virtual]
クラスで宣言された仮想関数は、そのクラスで定義されるか、純粋(10.4)と宣言されるか、またはその両方である必要があります。ただし、診断は必要ありません(3.2)。
したがって、関数を純粋仮想にするか、関数の定義を提供する必要があります。
gccのよくある質問doccumentsそれにも:
ISO C ++標準では、純粋仮想ではないクラスのすべての仮想メソッドを定義する必要があると指定されていますが、このルールの違反に対する診断は必要ありません。 [class.virtual]/8
。この仮定に基づいて、GCCは、暗黙的に定義されたコンストラクター、代入演算子、デストラクタ、および最初のそのような非インラインメソッドを定義する変換ユニット内のクラスの仮想テーブルのみを出力します。
したがって、この特定のメソッドを定義しなかった場合、リンカは明らかに無関係なシンボルの定義がないことについて不平を言う可能性があります。残念ながら、このエラーメッセージを改善するには、リンカーを変更する必要がある場合がありますが、これを常に実行できるとは限りません。
解決策は、純粋ではないすべての仮想メソッドが定義されていることを確認することです。純粋仮想として宣言されている場合でも、デストラクタを定義する必要があることに注意してください[class.dtor]/7
。