20

void ポインターに関する C と C++ の違いを理解しようとしています。以下は C でコンパイルされますが、C++ ではコンパイルされません (すべてのコンパイルは gcc/g++ -ansi -pedantic -Wall で行われます)。

int* p = malloc(sizeof(int));

mallocを返すためvoid*、C++ では代入が許可されていませんが、int*C では許可されています。

ただし、ここでは:

void foo(void* vptr)
{
}

int main()
{
    int* p = (int*) malloc(sizeof(int));
    foo(p);
    return 0;
}

C++ と C の両方で問題なくコンパイルできます。なんで?

K&R2 言う:

オブジェクトへのポインタはvoid *、情報を失うことなく型に変換できます。結果が元のポインター型に変換されると、元のポインターが復元されます。

そして、これvoid*は C での変換に関するすべてを要約したものです。C++ 標準は何を規定していますか?

4

3 に答える 3

38

C では、ポインターの変換void*は常に暗黙的でした。

C++ では、 からT*への変換void*は暗黙的void*ですが、それ以外への変換にはキャストが必要です。

于 2009-11-15T07:01:22.953 に答える
6

C++ は C よりも厳密に型指定されています。多くの変換、特に値の異なる解釈を意味する変換では、明示的な変換が必要です。C++のnew演算子は、明示的なキャストなしでヒープにメモリを割り当てるタイプ セーフな方法です。

于 2009-11-15T07:04:04.093 に答える
-1

ポインター型の変換では、追加の CPU 命令を実際に実行する必要がないことを理解しておくと便利です。それらは、開発者の意図を理解するためにコンパイル時に分析されます。void *不透明なポインターです。尖った物体の種類が不明だと言っているだけです。C は弱い型付けです。void *( ) と任意の ( T*) を暗黙的に直接変換できます。C++ は強く型付けされています。void *( ) から ( ) への変換はT*、厳密に型指定された言語の適切なケースにはなりません。しかし、C++ は C との下位互換性を維持する必要があったため、そのような変換を許可する必要がありました。指針となる原則は次のとおりです。明示的は暗黙的よりも優れています。void*したがって、 ( ) を特定の ( T*) ポインターに変換したい場合は、それをコードに明示的に記述する必要があります。( からの変換T*) から ( void*) への明示的な変換は必要ありません。(void*) ポインターに対して直接できることはあまりないからです (ただし、free() を呼び出すことはできます)。したがって、( T*) から ( void*) への変換はかなり安全です。

于 2009-11-15T07:22:40.867 に答える