最近、管理ポインタを学習し、以下のシナリオに遭遇しました。スタックオブジェクトのC++ shared_ptr
私はゲームビュー用のモデル/コントローラクラスを実装しています。私の見解は、モデル内のものをレンダリングします。かなりストレートです。私の主な機能には、私はこのような3つのすべてのインスタンスを作成:
RenderModel m;
m.AddItem(rect); // rect gets added just fine, it's an "entity" derivee
RenderView v;
v.SetModel(m);
はビュークラスをレンダリングマイ非常に簡単です:
class RenderView
{
public:
explicit RenderView();
~RenderView();
void Update();
void SetModel(RenderModel& model);
private:
// disable
RenderView(const RenderView& other);
RenderView& operator=(const RenderView& other);
// private members
boost::scoped_ptr<RenderModel> _model;
};
setviewコマンドの実装はかなり標準です:
void RenderView::SetModel(RenderModel& model)
{
_model.reset(&model);
}
これの鍵は、スマートポインタにモデルを保存するビューです。しかし、メインでは、モデルはスタックに割り当てられました。プログラムが終了すると、メモリは2回削除されます。意味あり。私の現在の理解では、(任意の種類の)smart_ptrに格納されるものは、スタックに割り当てられてはならないということがわかります。
上記の設定のすべての後、私の質問は簡単です:どのようにパラメータがスタックに割り当てられていないことを指示するのですか?唯一の解決策としてスマートポインタをパラメータとして受け入れていますか?
私はパラメータがスタックに割り当てられていなかったことを指示んか// If I implemented SetModel this way:
void RenderView::SetModel(const std::shared_ptr<RenderModel>& model)
{
_model.reset(&*model);
}
RenderModel m;
RenderView v;
std::shared_ptr<RenderModel> ptr(&m); // create a shared_ptr from a stack-object.
v.SetModel(ptr);
発信者がshared_ptrを誤って構成している場合は、このようなものを検出する方法がないと思いますか? 私はこのミスを再び犯すかもしれないと思うので、私は簡単に尋ねます。問題を再デバッグするのに何時間も費やしたくありません。私はそれが私の頭の中に燃え尽きるまで自分のモニターに付箋を残すことができました... – Short
アドレスを比較するような、オブジェクトがスタックかヒープに存在するかどうかを検出するための既知の「トリック」があります。これらはすべて、未定義または実装に依存する動作でリレーします。私はそれがうまくいくかもしれないと思っているが、本当の解決策ではないと思う。 –
いいえ、関数が 'std :: shared_ptr'を受け取った場合、そのポインタが有効なオブジェクトを指しているかどうかを判断する方法はありません。つまり、明示的に 'std :: shared_ptr'を取ると、(ローカル変数からの' std :: shared_ptr'を構成するコードは、最初の視点では間違って見えてしまい、避けるのは簡単です)。 –