38

GCC でコンパイルしているときにエラーが発生します: pure-specifier on function-definitionですが、VS2005 を使用して同じコードをコンパイルすると発生しません。

class Dummy {   
  //error: pure-specifier on function-definition, VS2005 compiles 
  virtual void Process() = 0 {};
};

ただし、この純粋仮想関数の定義がインラインでない場合は、次のように機能します。

class Dummy
{
  virtual void Process() = 0;
};
void Dummy::Process()
{} //compiles on both GCC and VS2005

エラーの意味は何ですか? インラインでできないのはなぜですか?2 番目のコード サンプルに示されているように、コンパイルの問題を回避することは合法ですか?

4

6 に答える 6

36

わかりました、私は何かを学びました。純粋仮想関数は、次のように宣言する必要があります。


class Abstract 
{
public:
   virtual void pure_virtual() = 0;
};

宣言の時点でボディを含めることは違法ですが、ボディを持っている場合もあります。つまり、本体を持つには、純粋仮想関数をクラスの外で定義する必要があります。本体がある場合でも、 から派生した具象クラスによって関数をオーバーライドする必要があることに注意してくださいAbstractAbstract::pure_virtual()必要に応じて明示的に呼び出すオプションがあるだけです。

詳細はこちら

于 2010-06-01T15:58:57.927 に答える
20

C++ 標準、10.4/2:

関数宣言は、純粋指定子と定義の両方を提供できません

于 2010-06-01T16:03:16.143 に答える
13

この構文:

virtual void Process() = 0 {};

合法的な C++ ではありませんが、VC++ でサポートされています。標準がこれを禁止している正確な理由は、私には明らかではありませんでした。2番目の例は合法です。

于 2010-06-01T16:00:10.483 に答える
4

C++ の純粋仮想関数は、定義上、宣言に定義がありません。

2 番目のコード ブロックは、コンパイラの問題を回避していません。意図したとおりに純粋な仮想関数を実装しています。

問題は、既定の実装を使用する場合、なぜそれを純粋仮想として宣言する必要があるのか​​ということです。

于 2010-06-01T16:01:42.540 に答える
3

これは文法的に許可されていません。pure -specifiersを含むことができる宣言子つまりmember-declaratorは、定義ではない宣言にのみ現れます。[class.mem] :

member-declaration : attribute-specifier-seq opt decl-specifier-seq opt member-declarator-list opt関数定義          [...]
          ;
         

メンバー宣言子リスト:
         メンバー宣言子
         メンバー宣言子リストメンバー宣言子

member-declarator :
         宣言子 virt-specifier-seq opt 純粋な指定子opt
         宣言子 中括弧または等号初期化子opt
         識別子opt 属性指定子-seq opt : 定数式

function-definitionの文法には、 pure-specifier [dcl.fct.def.general]は含まれません。

function-definition :
     attribute-specifier-seq opt decl-specifier-seq opt 宣言子 virt-specifier-seq opt 関数本体

于 2015-04-19T19:50:38.120 に答える
0

確かに、純粋な仮想関数の本体を提供できます。その関数は、その抽象クラス vtable によってポイントされます。__cxa_pure_virtualそうしないと、同じスロットがGCC のようなコンパイラ固有のトラップ関数を指します。もちろん、標準ではこれについて何もありません。

于 2010-06-01T16:09:10.307 に答える