Alexandrescuとwikipipidiaを読む私はpointeeと参照カウンターがヒープに格納されていることがわかります。次に、ヒープ上にカウンタを割り当てる必要があるため、参照カウントが非効率的であるという記述がありますか?スタックに格納されていないのはなぜですか?なぜC++スマートポインタの実装では、ヒープ上の参照カウンタをpointeeと共に保持していますか?
答えて
スマートポインタの現在のインスタンスが有効範囲外になるとすぐに失われるためです。
スマートポインタは、動的に割り当てられた自動ストレージオブジェクトをシミュレートするために使用されます。スマートポインタ自体は自動的に管理されます。だから1つが破壊されると、それが自動ストレージに保存されているものもすべて破壊されます。しかし、あなたは参照カウンタを失いたくはありません。したがって、動的ストレージに格納します。
オブジェクトをコピーするとrefcountのコピーが作成されるため、スタックに格納することはできません。これはその目的を無効にします。他の人が指摘したように
は、スタックは、オブジェクトが現在のスタックフレームよりも長生きするので、参照カウントを維持するために適切な場所ではありません(参照カウントが離れて行くだろう。その場合にはを!)
それは価値があります参照カウントをヒープに置くことに伴う非効率性のいくつかは、それをオブジェクト自体と「一緒に」格納することによって克服することができることに注意してください。これを高めるには、boost::make_shared(shared_ptrの場合)またはboost::intrusive_ptrを使用します。
異なる目的のために設計されたさまざまなタイプのスマートポインタがあります。あなたが話しているポインタは共有スマートポインタ(std::shared_ptr
)で、複数の場所からオブジェクトの所有権を共有するのに役立ちます。 shared_ptr
のすべてのコピーは、最初のコピーが終了した後でもshared_ptr
のすべてのコピーで使用可能である必要があるため、ヒープに配置された同じカウンタ変数を増減します。
したがって、shared_ptr
は内部的にオブジェクトとカウンタに2つのポインタを保持します。擬似コード:ところで
class SharedPointer<T> {
public:
// ...
private:
T* obj;
int* counter;
}
、あなたはstd::make_shared
を持つオブジェクトを作成するとき、実装はカウンタとオブジェクトの両方を保持するのに十分なメモリを割り当て、その後、彼らはサイド・バイ・サイド構成することによって配分を最適化することができます。
この極端なトリックは、内部的にカウンタを保持し、それをインクリメントおよびデクリメントするためのAddRef
およびRelease
関数を提供します。 侵入型スマートポインタを使用することができます。 boost::intrusive_ptr
は、この機械を使用しているため、別の別のカウンタを割り当てる必要はありません。これは割り当ての面では高速ですが、カウンタを制御されたクラス定義に挿入する必要があります。 std::unique_ptr
またはboost::scoped_ptr
:、あなたははスマートポインタをスコープ使用することができますが、共有オブジェクトの所有権を必要としてのみ、それは生涯のコントロールする必要はありません。また
は、(関数が返すときにつまり破壊されます)。 unique_ptr
のコピーが1つしか存在しないため、カウンタはまったく必要ありません。
- 1. スマートポインタ対参照
- 2. C++で定数参照を実装しています(weiss bookの後に)
- 3. c#List <myObject> myList.copyTo()は参照を保持しますか?
- 4. なぜ/アプリケーションは他のプロセスによって作成されたmutex参照を保持していますか?
- 5. C++に "NULL参照"がないのはなぜですか?
- 6. 「データベース間参照は実装されていません」と表示されるのはなぜですか?
- 7. ヒープと参照のオブジェクト
- 8. メソッドは参照平等を持っていないのはなぜですか?
- 9. 保持カウントと参照カウントの違いはどこですか?
- 10. NHibernateがデータオブジェクトへの参照を保持しています
- 11. なぜMontouchは、UIViewからUIViewControllerへの管理参照を保持していませんか?
- 12. C++でヒープの最小実装を抽出します
- 13. 参照をクラスメンバーとして使用できないのはなぜですか?
- 14. C++で任意のオブジェクト型への参照を保持しますか?
- 15. C++:なぜこのベクトルイテレータsegfaultを逆参照していますか?
- 16. arraylistのないヒープを実装します。
- 17. appriseの実装で、現在のスコープ外の$(this)を参照しています。
- 18. ChromeではTypedArraysがJSヒープ上にないのはなぜですか?
- 19. Objective-Cブロック - ブロックは参照するオブジェクトを保持しますか?
- 20. 配列のないMinMaxヒープ実装
- 21. C++/CLIで定数参照を実装するためのベストプラクティス
- 22. なぜC#ディクショナリはすべてIDictionaryを実装していませんか?
- 23. ヒープまたはスタックに参照が格納されていますか?
- 24. 弱参照のEventbusアクターを実装しますか?
- 25. 参照を保持しないオブジェクトのコピー
- 26. ヒープ上に大きなオブジェクトを持つことは悪いですか?
- 27. 参照として使用する単純なハッシュテーブルの実装例を探す
- 28. Javaで循環参照を持つオブジェクトのequalsとhashCodeを実装する
- 29. attr `android:popupEnterTransition`を参照できないのはなぜですか?
- 30. プライマリキーを参照できないのはなぜですか?
説明している内容の例を表示できますか? –
他にどのようにしますか? –
"参照カウンター"と "ヒープ"の両方が単なる実装の詳細です。実際の牛肉は、共有された所有権セマンティクスは動的割り当てでしか実装できないということです。 –