В последнее время я изучал управляемые указатели и столкнулся со следующим сценарием.
Я реализую класс модели/контроллера для игрового представления. Мой взгляд, сделает вещи в модели. Довольно прямо. В моей основной функции я создаю все три типа:
RenderModel m;
m.AddItem(rect); // rect gets added just fine, it 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);
}
Ключ к этому - представление хранит модель в интеллектуальном указателе. Однако в основном модель была выделена в стеке. Когда программа выходит, память удаляется дважды. Это имеет смысл. Мое настоящее понимание говорит мне, что все, что хранится в 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);