Stroustrupは2013 Going Nativeカンファレンスでこれについていくつかの良いコメントをしました。
この動画では、約25分50秒にスキップしてください。(私は実際にビデオ全体を見ることをお勧めしますが、これはガベージコレクションに関するものにスキップします。)
オブジェクトと値を直接(および明示的に)使用することを避けて(明示的に)使用することを避け、オブジェクト(および値)を直接処理することを簡単(かつ安全、予測可能、読みやすく、簡単に教える)に優れた言語がある場合ヒープ、そしてあなたもしませんしたいガベージコレクションを。
最新のC ++、およびC ++ 11にあるものでは、限られた状況を除いて、ガベージコレクションは望ましくありません。実際、優れたガベージコレクターが主要なC ++コンパイラーの1つに組み込まれていても、あまり使用されないと思います。それは次のようになります簡単に GCを避けるために、ではない難しく、。
彼はこの例を示しています:
void f(int n, int x) {
Gadget *p = new Gadget{n};
if(x<100) throw SomeException{};
if(x<200) return;
delete p;
}
これはC ++では安全ではありません。しかし、Javaでも安全ではありません。C ++では、関数が早く戻ると、delete
が呼び出されることはありません。しかし、Javaなどの完全なガベージコレクションがある場合、オブジェクトが「将来のある時点で」破棄されるという提案が表示されるだけです(更新:これはさらに悪いことです。Javaは、ファイナライザを呼び出すことを約束します-決して呼び出されることはありません)。ガジェットが開いたファイルハンドル、データベースへの接続、または後でデータベースへの書き込みのためにバッファリングしたデータを保持している場合、これは十分ではありません。これらのリソースをできるだけ早く解放するために、ガジェットが終了したらすぐに破棄する必要があります。データベースサーバーが、不要になった何千ものデータベース接続に悩まされることを望まない-プログラムが機能していることを知らない。
それで、解決策は何ですか?いくつかのアプローチがあります。オブジェクトの大部分に使用する明白なアプローチは次のとおりです。
void f(int n, int x) {
Gadget p = {n}; // Just leave it on the stack (where it belongs!)
if(x<100) throw SomeException{};
if(x<200) return;
}
これにより、入力する文字が少なくなります。new
邪魔になりません。Gadget
2回入力する必要はありません。オブジェクトは関数の最後で破棄されます。これがあなたが望むものであれば、これは非常に直感的です。 Gadget
sが同じに振る舞うint
かをdouble
。予測可能で、読みやすく、教えやすい。すべてが「価値」です。大きな値の場合もありますが、ポインタ(または参照)で得られるこの「遠くでのアクション」がないため、値を教える方が簡単です。
作成するオブジェクトのほとんどは、それらを作成した関数でのみ使用され、おそらく子関数への入力として渡されます。プログラマは、オブジェクトを返すときや、ソフトウェアの広く分離された部分でオブジェクトを共有するときに、「メモリ管理」について考える必要はありません。
範囲と寿命は重要です。ほとんどの場合、ライフタイムがスコープと同じであるほうが簡単です。理解しやすく、教えるのも簡単です。別の有効期間が必要な場合、shared_ptr
たとえば、これを使用して、これを実行しているコードを読み取ることは明らかです。(または(大きな)オブジェクトを値で返し、移動セマンティクスまたはを活用しますunique_ptr
。
これは効率の問題のように見えるかもしれません。ガジェットを返却したい場合はどうなりfoo()
ますか?C ++ 11の移動セマンティクスにより、大きなオブジェクトを簡単に返すことができます。書くGadget foo() { ... }
だけで動作し、すばやく動作します。&&
自分でいじる必要はありません。値によって物事を返すだけで、言語は必要な最適化を行うことができます。(C ++ 03より前でも、コンパイラーは不要なコピーを回避するために非常に優れた機能を果たしました。)
Stroustrupがビデオの他の場所で述べたように(言い換え):「オブジェクトをコピーしてから元のオブジェクトを破壊することを主張するのはコンピューターサイエンティストだけです(聴衆は笑います。)オブジェクトを新しい場所に直接移動しないのはなぜですか? (コンピューター科学者ではなく)期待しています。」
オブジェクトのコピーが1つだけ必要であることを保証できる場合は、オブジェクトの存続期間を理解する方がはるかに簡単です。必要なライフタイムポリシーを選択でき、必要に応じてガベージコレクションも利用できます。しかし、他のアプローチの利点を理解すると、ガベージコレクションが設定のリストの一番下にあることがわかります。
それでもうまくいかない場合は、を使用するunique_ptr
か、失敗してくださいshared_ptr
。よく書かれたC ++ 11は、メモリ管理に関して、他の多くの言語よりも短く、読みやすく、教えやすいです。