7

短いバージョン:
最新の C++ で非スマート ポインターを使用する理由はありますか?

長いバージョン:
古い C++ コードを多数含む巨大な製品があり、現在は最新の C++ 時代にリファクタリングしようとしています。すべての旧式のコードに加えて、膨大な量のポインターが渡されており (ほとんどの場合、ある程度のセキュリティを提供するために SAL 注釈が付けられています)、それらすべてをスマート ポインターに変更するか、一部をそのままにしておくべきか疑問に思っていました。 ? これらのコードのいくつかを変換しようとすると、スマート ポインターを使い
すぎていると単純に議論できるコードになってしまいました。

問題は、スマート ポインターの使い過ぎなどはあるのでしょうか。
言い換えれば、最近の非スマート ポインターに許容されるシナリオはありますか?

4

5 に答える 5

4

短いバージョン:
最新の C++ で非スマート ポインターを使用する理由はありますか?

簡潔な答え:

間違いなく、それらが観察のみに役立つ場合、つまり、それらはポインティを所有していません。ただし、この場合でもポインターの代わりに参照を使用するようにしてください。ポインターをオプションにする必要がある場合にのみポインターを使用してください (null_ptrたとえば、初期化して後で再割り当てするなど)。

長いバージョン:
古い C++ コードを多数含む巨大な製品があり、現在は最新の C++ 時代にリファクタリングしようとしています。[...]

長い答え:

これらの行を読んでいると、この答えが思い浮かびます。

この回答に複数回賛成できたらいいのにと思います。「[...]私たちが行ったリファクタリングごとに、『この特定の変更により、現在行っている実際のタスクがより簡単になる』ことを正当化できます。『これにより、将来の作業がよりクリーンになった』というよりも」

簡単に言えば、本当に必要でない限り、大きなリファクタリングを行わないでください。

問題は、スマート ポインターの使い過ぎなどはあるのでしょうか。

私の意見でstd::shared_ptrは、使いすぎです。とても快適に使用でき、所有権の問題について考える必要がないという錯覚を与えてくれます。しかし、それだけではありません。Sean Parentの次の言葉に完全に同意します。「共有ポインターはグローバル変数と同じくらい優れています。」共有ポインターは、非常に難しい所有権の問題などを引き起こす可能性もあります。

一方、ヒープに何かを割り当てる必要がある場合は、unique_ptr. 本当にヒープ割り当てが必要な場合は、使いすぎてはいけません。私の経験では、使用unique_ptrすると、所有権の問題が自明になるため、コードがよりクリーンで理解しやすくなります。

ポインターの使用を回避/削減する方法に関する Sean Parent の興味深い講演は次のとおりです。

お役に立てれば。

于 2013-10-17T16:20:15.010 に答える
3

はい、生のポインターには「オプションの参照」としての用途があります。つまり aT*は a に似ていT&ます。どちらも所有権を意味しませんが、 aT*は になりますnullptr

于 2013-10-17T09:02:27.120 に答える
0

もちろん、最新の C++ には生のポインターの使用例があります。

  • 純粋な C としてコンパイル可能でなければならないインターフェイス (ただし、実装自体は、クラスやスマート ポインターなど、C の機能ではない C++ の機能を利用する場合があります)
  • 非常に低レベルのコード、非常に低レベルであるため、最も単純なスマート ポインターでさえ、重量が重いことが証明されます。

もちろん、これらはかなりまれなケースであり、ポインターのほとんどのユースケースでは、スマートポインターは新しいコードには問題ありませんが、次のようになります。

既存のコードが未加工のポインターで問題なく動作する場合、バージョンを使用してスマート ポインターに変換するときに、時間をかけてコードを書き直し、バグを追加するリスクを冒す必要はありません。

新しいコードが最新のプログラミング標準によりよく準拠しているという理由だけで、正常に機能しているコードをリファクタリングしないでください。これらのプログラミング標準は、それ自体のために存在するのではなく、一部のコードの操作を容易にするためのものです。リファクタリングは行わないでください。リファクタリングを行うと、将来節約できるよりも多くの時間を費やすことになります。

つまり、これらのポインターのどれが安全にスマートポインターに変換でき、どれが変換できないかを確認するのに時間がかかる場合、リファクタリングによって導入された可能性のあるバグを追跡することで、保存できるよりも多くの時間を費やすことができます。リファクタリングによる将来の保守作業については、単にリファクタリングを行わずにそのままにしておいてください。

コード ベースの一部だけをリファクタリングすることでコストよりも多くの時間を節約できる場合は、コード ベースのそれらの部分のみをリファクタリングすることを検討してください。

于 2013-10-17T15:58:04.613 に答える
0

ここで講演をチェックしてください: http://channel9.msdn.com/Events/GoingNative/2013 (特に Stroustrup の講演)。

「最新の C++」が >= c++11 であると仮定すると、短い答えはノーです。

長い答えは、常にそうであるとは限らず、大規模なプロジェクトを再構築しようとすることは、ほとんどの場合困難であるということです。問題に対する私たちの考え方は、問題を解決するために必要なツールによって制約されます。このようなリファクタリングを行う場合、基本的なロジックをクラスやスマート ポインターに適したものに再表現するよりも、単にポインターを使用する方が理にかなっている場合が多くあります。スマート ポインターが過剰に使用されている場合よりも、クラスが十分に使用されていない場合の方が多いと思います。YMMV ;-)

于 2013-10-17T03:21:37.953 に答える