Я изучал управляемых указателей в последнее время и столкнулся с следующим сценарием.
Я реализую класс модели / контроллера для просмотра игры. Мой взгляд, сделает вещи в модели. Довольно прямо вперед. В моей главной функции я создал все трое:
RenderModel m;
m.AddItem(rect); // rect gets added just fine, it's an "entity" derivee
RenderView v;
v.SetModel(m);
Мой класс View View довольно прост:
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);