163

純粋仮想関数は常に次のように宣言します。

virtual void fun () = 0 ;

つまり、常に 0 が割り当てられます。

私が理解しているのは、これはこの関数の vtable エントリを NULL に初期化することであり、ここに他の値があるとコンパイル時エラーが発生するということです。この理解は正しいですか?

4

11 に答える 11

170

使用される理由=0は、Bjarne Stroustrupが、機能が実装されていたときにC++コミュニティを超えて「純粋」などの別のキーワードを取得できるとは考えていなかったためです。これは、彼の著書、The Design&Evolution of C ++、セクション13.2.3で説明されています。

好奇心旺盛な=0構文が選択されました...当時、新しいキーワードが受け入れられる可能性がなかったためです。

彼はまた、これはvtableエントリをNULLに設定する必要はなく、そうすることは純粋仮想関数を実装する最良の方法ではないと明示的に述べています。

于 2010-01-28T17:54:14.947 に答える
81

C++ の設計に関するほとんどの「なぜ」の質問と同様に、最初に参照する場所は、Bjarne Stroustrup 1によるThe Design and Evolution of C++ です

新しいキーワードを導入するという明らかな代替手段よりも、または 当時、新しいキーワードが受け入れられる可能性がなかったために、奇妙な=0構文が選択されました。私が提案していたら、リリース 2.0 は抽象クラスなしで出荷されていたでしょう。より優れた構文と抽象クラスのどちらかを選択できるように、私は抽象クラスを選択しました。遅延の危険を冒し て . この構文は、関数本体が関数の初期化子であり、関数ポインターのベクトルとして実装されている仮想関数のセットの (単純ですが、通常は適切な) ビューを備えているという私の見解に適合します。[ ... ]pureabstractpurepure=0

1 §13.2.3 構文

于 2010-01-28T18:02:32.953 に答える
31

C ++標準のセクション9.2は、クラスメンバーの構文を示しています。これには、このプロダクションが含まれます。

pure-specifier:
    = 0

値について特別なことは何もありません。「=0」は、「この関数は純粋仮想です」という構文にすぎません。初期化またはnullポインター、あるいは数値ゼロとは何の関係もありませんが、それらとの類似性にはニーモニック値がある場合があります。

于 2010-01-28T17:57:02.850 に答える
18

この背後に何らかの意味があるかどうかはわかりません。それは単なる言語の構文です。

于 2010-01-28T17:52:27.637 に答える
16

新しい予約語は、これらの単語を識別子に使用する古いプログラムを壊すため、C++は常に新しいキーワードの導入を避けてきました。古いコードを可能な限り尊重することは、言語の長所の1つと見なされることがよくあります。

構文は= 0、vtableエントリをに設定することに似ているため、実際に選択されている可能性がありますが0、これは純粋にシンボリックです。(ほとんどのコンパイラは、プログラムを中止する前にエラーを発行するスタブにそのようなvtableエントリを割り当てます。)構文は主に、以前は何にも使用されておらず、新しいキーワードの導入を節約したために選択されました。

于 2010-01-28T17:57:11.120 に答える
11

C++ には、純粋仮想関数を通常の仮想関数の宣言と区別する方法が必要です。彼らは= 0構文を使用することを選択しました。純粋なキーワードを追加することで、同じことを簡単に行うことができたはずです。しかし、C++ は新しいキーワードを追加することを非常に嫌い、他のメカニズムを使用して機能を導入することを好みます。

于 2010-01-28T17:52:52.367 に答える
7

この場合、ゼロが「初期化」または「割り当て」られることはありません。とトークンで= 0構成される構文構造であり、初期化や割り当てとはまったく関係ありません。=0

「vtable」の実際の値とは関係ありません。C ++言語には、「vtable」などの概念はありません。さまざまな「vtables」は、特定の実装の単なる詳細にすぎません。

于 2010-01-28T17:54:04.997 に答える
3

面白い構文の正当性は、同じことをする別のキーワードを導入するよりも(標準の受け入れに関して)簡単だったということを読んだことを覚えています。

これは、BjarneStroustrupによるC++の設計と進化で言及されたと思います。

于 2010-01-28T17:54:35.307 に答える
2

純粋仮想関数= 0を宣言します。

これは、この関数のvtableエントリをNULLに初期化することであり、ここで他の値を指定すると、コンパイル時エラーが発生することを理解してください。

それは本当ではないと思います。ただの特別な構文です。vtableは実装定義です。純粋なメンバーのvtableエントリは、構築時に実際にゼロにする必要があるとは誰も言いません(ただし、ほとんどのコンパイラは同様のvtableを処理します)。

于 2010-01-28T17:55:22.623 に答える
2

これは C++ 文法の一部にすぎないと思います。特定のバイナリ形式に対してコンパイラが実際にこれを実装する方法に制限はないと思います。初期の C++ コンパイラでは、おそらくその想定が正しかったと思います。

于 2010-01-28T17:52:43.477 に答える
1

実際の関数を指すようにvtableエントリを初期化することもできます。」

 virtual void fun()
 {
     //dostuff()
 }

vtableエントリは、nowhere(0)または関数を指すように定義できることは直感的に思えます。独自の値を指定すると、関数ではなくガベージを指すようになる可能性があります。ただし、「= 0」は許可され、「=1」は許可されないのはそのためです。ニール・バターワースは、なぜ「=0」が使用されているのかについて正しいと思います

于 2010-01-28T17:56:19.000 に答える