2012-02-14 7 views
5

Alexandrescuとwikipipidiaを読む私はpointeeと参照カウンターがヒープに格納されていることがわかります。次に、ヒープ上にカウンタを割り当てる必要があるため、参照カウントが非効率的であるという記述がありますか?スタックに格納されていないのはなぜですか?なぜC++スマートポインタの実装では、ヒープ上の参照カウンタをpointeeと共に保持していますか?

+0

説明している内容の例を表示できますか? –

+0

他にどのようにしますか? –

+0

"参照カウンター"と "ヒープ"の両方が単なる実装の詳細です。実際の牛肉は、共有された所有権セマンティクスは動的割り当てでしか実装できないということです。 –

答えて

9

スマートポインタの現在のインスタンスが有効範囲外になるとすぐに失われるためです。

スマートポインタは、動的に割り当てられた自動ストレージオブジェクトをシミュレートするために使用されます。スマートポインタ自体は自動的に管理されます。だから1つが破壊されると、それが自動ストレージに保存されているものもすべて破壊されます。しかし、あなたは参照カウンタを失いたくはありません。したがって、動的ストレージに格納します。

3

オブジェクトをコピーするとrefcountのコピーが作成されるため、スタックに格納することはできません。これはその目的を無効にします。他の人が指摘したように

1

、スタックは、オブジェクトが現在のスタックフレームよりも長生きするので、参照カウントを維持するために適切な場所ではありません(参照カウントが離れて行くだろう。その場合にはを!)

それは価値があります参照カウントをヒープに置くことに伴う非効率性のいくつかは、それをオブジェクト自体と「一緒に」格納することによって克服することができることに注意してください。これを高めるには、boost::make_shared(shared_ptrの場合)またはboost::intrusive_ptrを使用します。

1

異なる目的のために設計されたさまざまなタイプのスマートポインタがあります。あなたが話しているポインタは共有スマートポインタ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つしか存在しないため、カウンタはまったく必要ありません。

関連する問題