web-dev-qa-db-ja.com

関数定義の純粋な指定子

GCCでコンパイルしているときに、エラー:function-definitionのpure-specifierが表示されますが、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番目のコードサンプルに示されているように、コンパイルの問題を回避することは合法ですか?

35
Bébul

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

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

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

詳細は ここ です。

33
Dima

C++標準、10.4/2:

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

19
Paul

この構文:

virtual void Process() = 0 {};

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

13
anon

純粋仮想関数C++の場合定義上定義はありません宣言の場合

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

質問するのは、デフォルトの実装を使用する場合、なぜ純粋な仮想として宣言する必要があるのか​​ということです。

4
Amardeep AC9MF

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

member-declaration
attribute-specifier-seqoptdecl-specifier-seqoptmember-declarator-listopt;
function-definition
[...]

member-declarator-list
member-declarator
member-declarator-listmember-declarator

member-declarator
宣言子virt-specifier-seqopt純粋な指定子opt
declarator brace-or-equal-initializeropt
識別子optattribute-specifier-seqopt:定数式

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

function-definition
attribute-specifier-seqoptdecl-specifier-seqopt宣言子virt-specifier-seqoptfunction-body

3
Columbo

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

0