0

Cでの使用には多くの欠点がありますvoid *(メモリ関連、型関連、効率など)。それらにもかかわらず、私たちはそれらが提供する柔軟性のためにそれらを多く使用しています.

を使用して欠点/欠点をリストしますvoid *(および可能であればCでの推奨ソリューション)。

編集: 次のリンクを参照してください: http://attractivechaos.wordpress.com/2008/10/02/using-void-in-generic-c-programming-may-be-inefficient/

4

6 に答える 6

15

void ポインターには効率の問題はありません。void ポインターの唯一の制限は次のとおりです。

  • 明らかな理由で void ポインターを逆参照することはできません
  • sizeof(void)違法です
  • void ポインターに対してポインター演算を実行することはできません

ただし、GCC はそれが 1 であると想定しsizeof(void)、void ポインターでのポインター演算を許可します -こちらを参照してください

于 2008-12-04T08:31:46.400 に答える
14

質問の前提に同意しません。C で void* を使用するのは、ポリモーフィズムを取得する唯一の方法だからです。例: ライブラリ関数 qsort および bsearch。void * に基づくポリモーフィズムは安全ではないという欠点が 1 つだけあります: void * にポインターをキャストすると、その void * を誤って間違ったポインター型にキャストすることを防ぐものは何もありません。私の生徒はよくこの間違いをします。

ポリモーフィック データ構造を使用するためにヒープ領域を割り当てる必要がある場合があるため、効率が低下する可能性があります。

void * でポリモーフィック データ構造を使用する利点とトレードオフを確認したい人は、Dave Hanson の著書C Interfaces and Implementationsのコピーを入手する必要があります。

于 2008-12-04T08:34:13.290 に答える
3

ええと...そんなにたくさんあるとは思いません。もちろん、必要がないvoid*ときは絶対に使用しないでください。使用できる明確に定義されたタイプがある場合は、それを実行します。

私の経験では、の戻り値のように、ビットの不透明なバッファーを処理する場合のvoid*ように、「匿名」ポインター (なんてショック!) に最適です。malloc()多くの場合、たとえばバイト レベルでこれらのバッファをアドレス指定したい場合unsigned char *は、もちろん を使用します。

void*ポインターが必要な場所でランダムに使用するだけでは、コードが壊れて臭くなり、もちろん避ける必要があります。

于 2008-12-04T08:29:29.180 に答える
2

リンク先の投稿では、void ポインターを使用した操作と C++ テンプレートを使用した操作を比較し、テンプレートの方が効率的であると結論付けています。これは驚くことではありません。私が見た C++ コードでは、void ポインターはほとんど、またはまったく使用されていません。一般に、他の C++ 機能に勝る利点はなく、型システムの大きな穴になる可能性があります。

ただし、C には C++ スタイルのテンプレートがなく、データ型に依存しない必要がある機能を実装するには、void ポインターが必要です。

したがって、C で記述していて汎用性が必要な場合、void ポインターはそれを取得する最も効率的な手段です (それらが唯一の手段であるため)。C++ で記述している場合、void ポインターで実現できるほとんどすべてのことを行うためのより良い方法があるため、それらを使用しないでください。

于 2008-12-04T20:24:47.817 に答える
1

あなたの与えられたリンクは、部分的に真実です。特に、オブジェクト (構造体) を扱っていない場合、または一般的にまだ割り当てられていない型を扱っている場合。int、double などのネイティブ型と void ポインター (コンテナーなど) を使用することは、ほとんどの場合厄介な問題です。データ型に追加のメモリを割り当てる必要があります。

最初の選択は、移植性がなく、値として 0 が許可されていない可能性があり、単純に気分が悪いため、悪いです。2番目の選択肢はメモリを浪費し、余分な割り当てのために実際に(大規模な)速度低下を引き起こします。

しかし、ほとんどの場合、ネイティブ型を扱っているのではなく、既に割り当てられているオブジェクトへのポインタを使って、オブジェクトを扱っています。少なくとも私はそうしています。整数や倍精度のハッシュ テーブルやマップは必要ありませんでした。また、ポインターのタイプセーフのためだけに異なるコンテナー実装を使用することは、私には間違っているように感じます。実装ごとにバイナリサイズが増加するためです。したがって、ポインタを格納するためのコンテナのみが必要な場合は、void ポインタを使用しても速度が低下したり、メモリが無駄になったりすることはありません。

ただし、これはコンテナの実装に関するものでした。ところで、あなたが言及したブログ記事のように。一般に、void ポインターを使用しないと達成できないことがたくさんあります。

于 2008-12-04T14:46:51.837 に答える
1

わかりませんが、さまざまなレベルの抽象化 (ABC) にアクセスするには、void ポインターが非常に効果的であることがわかりました。さまざまな抽象化レベルで相互リンクされたクラスをナビゲートする手段として。とてもシンプルで、素晴らしいです。e や黄金比の公式のように、空虚*を崇拝するオカルトがあるはずです :)

于 2010-02-21T05:46:21.790 に答える