Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
110 views
in Technique[技术] by (71.8m points)

c++ - 堆栈对象的c ++ shared_ptr(c++ shared_ptr of stack object)

I have been learning managed pointers lately and ran into the following scenario. (我最近一直在学习托管指针,并遇到以下情况。)

I am implementing a model/controller class for a game view. (我正在为游戏视图实现模型/控制器类。) My view, will render things in the model. (我的观点是,将在模型中渲染事物。) Pretty straight forward. (非常简单。) In my main function, I instantiate all three like this: (在我的主要功能中,我将所有三个实例化为:)

RenderModel m;
m.AddItem(rect); // rect gets added just fine, it's an "entity" derivee
RenderView v;
v.SetModel(m);

My render view class is pretty straightforward: (我的渲染视图类非常简单:)

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;
};

The implementation for setView is pretty standard: (setView的实现是非常标准的:)

void RenderView::SetModel(RenderModel& model)
{
    _model.reset(&model);
}

The key to this is, the view stores a model in a smart pointer. (关键在于,视图将模型存储在智能指针中。) However in main, the model was allocated on the stack. (但是总的来说,模型是在堆栈上分配的。) When the program exits, the memory gets deleted twice. (程序退出时,内存将被删除两次。) This makes sense. (这很有道理。) My current understanding tells me that anything which gets stored in a smart_ptr (of any kind) should not have been allocated on the stack. (我目前的理解告诉我,存储在smart_ptr中的任何内容(任何种类)都不应该在堆栈上分配。)

After all the above setup, my question is simple: how do I dictate that a parameter was not allocated on the stack? (完成上述所有设置后,我的问题很简单:如何指示未在堆栈上分配参数?) Is accepting a smart pointer as a parameter the only solution? (接受智能指针作为参数是唯一的解决方案吗?) Even then I could not ensure that someone using my view class could not do something incorrect such as: (即使那样,我也无法确保使用我的视图类的某人不能做一些不正确的事情,例如:)

// 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);
  ask by Short translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

how do I dictate that a parameter was not allocated on the stack? (我该如何指示未在堆栈上分配参数?)

Yes, require the caller to provide a std::shared_ptr<RenderModel> . (是的,要求调用者提供std::shared_ptr<RenderModel> 。) If the caller misconstructs the std::shared_ptr , that's the caller's problem, not yours. (如果调用方构造错误的std::shared_ptr ,那是调用方的问题,而不是您的问题。)

If you intend for a RenderView to be the sole owner of a particular RenderModel , consider having the function take a std::unique_ptr or std::auto_ptr instead; (如果您打算让RenderView成为特定RenderModel的唯一所有者,请考虑让该函数采用std::unique_ptrstd::auto_ptr代替;) this way it is clear that the caller should not retain ownership of the object after it calls the function. (这样,很明显,调用者在调用函数后不应保留对象的所有权。)

Alternatively, if RenderModel is cheap to copy, make a copy of it and use the copy: (或者,如果RenderModel复制便宜,请对其进行复制并使用该副本:)

_model.reset(new RenderModel(model));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...