質問

Cでvoid *を使用することには多くの欠点があります(メモリ関連、タイプ関連、効率的に...)。それらにもかかわらず、それらが提供する柔軟性のために多く使用します。

<=>を使用してデメリット/欠点をリストします(可能であればCでの推奨ソリューション)。

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

役に立ちましたか?

解決

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

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

ただし、GCCは<=>が1であると想定し、voidポインターでのポインター演算を許可します-こちら

をご覧ください

他のヒント

質問の前提に同意しません。 Cではvoid *を使用します。これは、ポリモーフィズムを取得する唯一の方法だからです。例:ライブラリー関数qsortおよびbsearch。唯一の欠点があります。これは、void *に基づくポリモーフィズムが安全でないことです。void*にポインターをキャストすると、そのvoid *を wrong ポインタータイプにキャストすることを妨げるものは何もありません。間違い。私の学生はこの間違いを頻繁に犯します。

多態的なデータ構造を使用するためにヒープスペースを割り当てることが必要な場合があるため、効率が低下する可能性があります。

void *を含むポリモーフィックデータ構造を使用することの利点とトレードオフを確認したい場合は、Dave Hansonの本 Cインターフェースと実装

えーと...そんなにたくさんあるかわかりません。もちろん、必要がないときはvoid*を決して使用しないでください。使用できる明確に定義された型がある場合は、それを実行します。

私の経験では、malloc()は<!> quot; anonymous <!> quotに最適です。 unsigned char *の戻り値の場合や、不透明なビットバッファを処理する場合のように、ポインタ(なんと衝撃的でしょう!)多くの場合、これらのバッファは、たとえばもちろん、バイトレベルを使用してから、<=>を使用します。

ポインターを必要な場所で<=>をランダムに使用するだけで、壊れてしまい、臭いコードになり、もちろん回避できます。

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

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

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

指定されたリンクは部分的に正しいです。特に、オブジェクト(構造体)を扱っていない場合、または一般的にはまだ割り当てられていない型を扱っている場合。 int、doublesなどのネイティブ型とvoidポインター(コンテナーなど)の使用は、ほとんど常に厄介な問題です。なぜなら、intをキャストするか(doubleの場合は機能しません)、ポインターにキャストするか、データ型に追加のメモリを割り当てる必要があります。

最初の選択は移植性がなく、0は値として許可されず、単に気分が悪いため、まずい選択です。 2番目の選択はメモリを浪費し、実際に余分な割り当てのために(大規模な)スローダウンです。

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

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top