2011-06-28 8 views
0

その有効性を確認する:参照オブジェクトに指摘し、次を考える

class Curve { 
public: 
    typedef boost::shared_ptr<Curve> Pointer; 
    // ... 
private: 
    // ... 
}; 

class CurveShift: public Curve { 
public: 
    CurveShift(const Curve & curve); 
    // ... 
private: 
    const Curve & curve_; 
    // ... 
}; 

私はあなたのような何かをしたいときに使用するコンセンサスのベストプラクティスがあるかどうかを疑問に思った:

Curve::Pointer pointer(new Curve()); 
SomeGlobalRepository::Add("key", pointer); 

そして、あなたが持っているいくつかの他の場所で:

CurveShift cs(*SomeGlobalRepository::Get("key")); 

あなたは本当に任意の保証のトンを持っていませんhat SomeGlobalRepositoryには、CurveShiftが必要な場合は元のCurve::Pointerが含まれているため、curve_は、割り当て解除されたメモリ、または既に別のものに再割り当てされたメモリを指している可能性があります。私は可能な解決策はCurveShiftconst Curve &の代わりにboost:weak_ptr<Curve>を使用することであると確信していますが、私はもうCurveをスタック上で使用することができず、どのインスタンスもヒープコンストラクタはプライベートになり、オブジェクトは工場を通じて作成されます)。望ましい行動を達成するためのより良い戦略はありますか?理論的にはこれは深刻な問題になるかもしれないが、実用的なユースケースはこれらの難しい状況を生み出すことには役に立たないだろうと私は感心している。

+2

なぜ 'CurveShift'は' shared_ptr '自体を保持していませんか?それは、「共有」がすべてのものであることのようなものです... – Nemo

+0

カーブのネットワークにサイクルが含まれているかどうかそうでなければ、すべては 'shared_ptr'でなければなりません。 'CurveShift'は参照を保持しているので、' CurveShift'はそれ以前に作成された 'Curve'を参照することしかできないので、私はどのようにサイクルが賢明になるのか分かりません。 'CurveShift'はサイクルを作成するために参照することができますが、それは非常に賢明ではないようです... –

+0

シフトされるカーブがスタックに割り当てられている場合、shared_ptrをどのように取得しますか? – Hazerider

答えて

2

shared_ptrがある場合、オブジェクトは有効として維持されます。もちろん、生のリファレンスは必ずしも有効であるとは限りません。単にcurve_shared_ptrにするのはなぜですか? weak_ptrはサイクルを中断するように設計されています。ここにはサイクルがないので、理由はないはずです。

3

ことがある場合、私はあなたがする... std::shared_ptrをしたいあなたは、スタック上に割り当てられたオブジェクトを持って、あなたのコメントに気づいた(私はあなたの質問から欠落していますここにあなたのデザインを制約する何かがあると思います)その後、ヒープ上のスタック・オブジェクトのコピーを割り当て、そのヒープに割り当てられたからstd::shared_ptrを作成します

std::shared_ptr<my_object_t> sh_ptr(new my_object_t(stack_object)); 

:場合、あなたのような何かをしてヒープにスタックからあなたのオブジェクトをコピーする必要がありますオブジェクト。その後、

はまた、私はあなたがCurveShiftshared_ptrのコピーではなく、Curveクラスオブジェクトへの一定の基準を保持するクラスを持つべきニモのコメントに同意しまうなど、容器の中に新しく作成した共有ポインタをコピーすることができます。そのようにしてshared_ptrオブジェクトはポインタ参照の存続時間を制御し、コンテナや他のオブジェクトが自身の分解中にshared_ptrインスタンスが指すメモリを破壊しようとすると、メモリ参照は引き続き維持されます他の場所のshared_ptrのデストラクタを呼び出すことからCurveShiftインスタンスは、CurveShiftインスタンスオブジェクトがアクティブであるため、ヒープ上のオブジェクトのメモリを実際に割り当て解除しませんshared_ptrによって保持されているそのヒープ割り当てオブジェクトへの参照。一定の参照だけを保持することで、何らかの形の参照カウントによってヒープに割り当てられたオブジェクトの制御解除された型であるshared_ptr型を使用することの利点をすべて取り除くことができます。最後に

、私はあなたのようなクラスを記述します。

class CurveShift: public Curve { 
public: 
    CurveShift(const shared_ptr<Curve>& ptr): _curve(ptr) 
    { 
     // ... rest of constructor 
    } 

private: 
    shared_ptr<Curve> curve_; //will remain valid for lifetime of CurveShift instance 
    // ... 
}; 

そして、あなたは次のように電話をかけるでしょう:あなたのCurveShiftインスタンスにどのshared_ptrでコピー

CurveShift cs(SomeGlobalRepository::Get("key")); 

と増加ヒープ上のポインタへの参照カウント。

+0

+1 - 最初のコードスニペットでは、代わりに 'std :: make_shared'を推奨します。そのような方法で無名の 'shared_ptr'を作成するべきではありません。なぜなら、例外がスローされ、コンパイラが呼び出しをどのように注文するかにあなたが好ましくない場合、メモリリークにつながる可能性があるからです。 –

+0

Scott MeyersのEffective C++を参照してください。Item#17:スタンドアローンステートメントでスマートポインタに新しいオブジェクトを格納します。 –

+0

@Billy ONeal:チップをありがとう...コードを更新しました。 – Jason

関連する問題