web-dev-qa-db-ja.com

C ++ 11ガベージコレクター-理由と方法

C++ 11の言語機能リスト には以下が含まれます。

ガベージコレクションと到達可能性に基づくリーク検出の最小限のサポート

(ただし、GCCとClangのどちらにも実装されていないようです。)

標準委員会がこのガベージコレクションのC++言語機能を導入した理由は何ですか。

C++には本当にGCが必要ですか? RAIIはそのような優れたパターンではありませんか(ソケット、ファイル、テクスチャなどのメモリリソースと非メモリリソースの両方に均一に使用できます)。

GCはRAIIを使用するC++コードパターンの均一性を壊しますか?

一部の人々は、循環依存を解消するためにGCが便利になると言いますが、この目的のためにweak_ptrのようなスマートポインターを使用するだけで十分ではないでしょうか?

また、例外がスローされた場合はどうなりますか?スタックアンワインドセマンティクスは、GCを考慮するためにどのように変更されますか?

また、C#に似たIDisposableパターンも導入されますか?

さらに、GCがC++で導入されていると仮定すると、ポインターの構文は異なりますか?例えばC++/CLIまたはC++/CX拡張機能のような帽子のような「ポインタ」^はありますか?通常の生のポインタと「管理された」ポインタとを区別する方法があるはずですよね?

40
Mr.C64

この提案はガベージコレクターを導入していません-特定の状況でそれを許可するだけです実装が選択した場合。標準は、これらの状況を未定義の動作を引き起こすものとして説明します。これにより、実装の要件が緩和され、ガベージコレクターに最小限の余裕が与えられます。

プロポーザル で与えられた簡単な例は、動的に割り当てられたオブジェクトへのポインタを取得するときに考慮しますXOR別の値でそれを行い、それによりポインタ値を非表示にしてから回復しますそれを介してオブジェクトにアクセスするための元のポインター値。C++ 11より前は、これは完全に問題なく使用できます。ただし、このような操作は(次の段落を参照)未定義の動作と見なされる可能性があります。つまり、その実装may指されたオブジェクトでガベージコレクションを実行します。

標準では、実装はリラックスしたポインタの安全性のいずれかであり、その場合の動作は以前と同じであるか、または厳密なポインタの安全性であるガベージコレクター。

実装にはrelaxed pointer safeが含まれる場合があります。その場合、ポインター値の有効性は、安全に派生したポインター値であるかどうかには依存しません。または、実装にstrict pointer safeが含まれる場合があります。この場合、参照された完全なオブジェクトが動的ストレージ期間であり、以前に持っていなかった場合を除き、安全に派生したポインタ値ではないポインタ値は無効なポインタ値です。到達可能と宣言された(20.6.4)。 [...]実装が緩和されているか、厳密なポインタの安全性であるかは、実装によって定義されます。

ポインター値は、動的に割り当てられたオブジェクトを指していて、それにおかしなビジネスが発生していない場合、安全に派生したポインター値です(§3.7.4.3でより具体的に定義されています)。

実装が厳密なポインターの安全性を備えているにもかかわらず、未定義の動作を導入せずにポインターに対して変なビジネスをしたい場合は、次のようにポインターpが到達可能であると宣言できます。

declare_reachable(p);

この関数は、<memory>ヘッダーで、undeclare_reachabledeclare_no_pointersundeclare_no_pointersなどの関連関数とともに定義されます。 get_pointer_safetyを使用して、実装の厳格さを判断することもできます。

55

Bjarne Stroustrupから:

実際、私が言ったのは「自動ガベージコレクションがC++の一部になると(ない場合)、それはオプションになります」のようなものでした。

http://www.stroustrup.com/slashdot_interview.html

19
fjardon