C++ツールとライブラリは、これまで以上に強力になりました。
たとえば、配列をベクトルに置き換えることができます。ポインタを参照で置き換えることができます。スマートポインターを使用できます。
生のポインターの使用を避けることは、プロのプログラマーの間で一般的な習慣ですか?
(デバイスドライバーではなくエンタープライズFooの作成について話しているように)十分に高いレベルであり、外部依存関係がない新しいグリーンフィールドプロジェクトを開始する場合は、ポインターの使用を完全に回避できます。しかし、ほとんどの開発はまったく新しい開発ではなく、間違いなくポインタを含むC++コードの何百万もの既存の行を活用しています。また、新しいアプリケーションでさえ、ほとんどの場合、ポインタを頻繁に使用する外部ライブラリや他のAPIに依存しています。したがって、ポインタなしで完全に構築できるアプリケーションのセットはかなり小さいです。
ポインタを使用するために必要なコードベースの量を最小限に抑えることができる場合があります。ポインタに依存しないさまざまなライブラリを見つけることができる場合があります(ただし、これは通常、パフォーマンスまたは機能性を犠牲にします)。ポインタに依存する既存のコードとライブラリの上に独自のインターフェイスを作成し、新しいコードベースの大部分でその新しいインターフェイスを使用できます。ただし、新しいレイヤーを追加し始めると、ほとんどの場合、パフォーマンスや柔軟性が犠牲になります。これらのトレードオフが許容できるかどうかは、アプリケーションに大きく依存します。
人間として、私たちは間違いを犯しやすく、間違いを犯しやすいです。したがって、できるだけ安全にプログラムを作成し、コンパイラやValgrindなどのツールを使用して、本番環境でクラッシュする前に問題を発見できるようにする必要があります。
すべてのレベルでポインタを回避することは不可能であることは明らかです–それらは複雑なアーキテクチャにとって非常に貴重な間接化のメカニズムを提供します–「コンピュータサイエンスのすべての問題は、もちろん、多くの間接参照」(ウィーラーの法則)。ただし、生のポインターは、私たちまたはコンパイラーが効率的に推論するには強力すぎる。
C++は、プログラマーがポインターのようなものを使用している理由をより正確に示すことができるいくつかのメカニズムを提供します。
std::unique_ptr
_はゼロコストの抽象化であるため、ポインターに明確な所有者がいる場合は常に、スマートポインターを使用すると安全性が確実に向上します。std::vector
_や_std::string
_などのSTLタイプは、配列のようなポインターのほとんどの使用法を置き換え、適切なライフタイム管理、適切なコピーを導入し、正しく使用するとバッファーオーバーランが発生する可能性が低くなり、非効率的でさえありません。残念ながら、それらには安全でない_operator[]
_がありますが、代わりに境界チェック済みの.at()
を使用するオプションがあります。これらのソリューションは完璧ではありませんが、危険で間違ったコードを書くことをより困難にします。 Cの互換性または(共有ポインターの場合は、ベクターのいくつかの使用シナリオ)オブジェクトサイズを最適化しない限り、この安全性を忘れる理由はありません。参照、イテレーター、スマートポインター、またはコレクションが、生のポインターよりも問題に対するより優れた、より自己文書化された、より正確な解決策ではなかった良い例をまだ見ていません。
これらの安全機能を使用することは専門家ですか?はい:問題を正しく効率的に解決することは専門家です。 segfault、バッファオーバーラン、メモリリークのデバッグは、時間を効率的に使用するものではないため、最初から避けたいと思います。半分以上のIDEまたはエディター(およびC++ 11のauto
)を使用すると、これは入力するコードがさらに多くなることはありません。
No、それ自体は回避されません。
longそれらが存在するもののリストnotが適切な「生の」ポインタを適切に使用します。
これを短くするには:
delete
は避け、ネイキッドnew
-> _make_shared
_または_make_unique
_は友だちにしないでください)f(int* pOptValue)
ここで、ユーザーはnullptr
を渡して値がないことを示すことができます。 (代わりに、_optional<int>
_の代わりに長い議論を始めることができると確信していますが。)