2016-08-30 57 views
0

我有一个类通过它暴露的接口增加功能:接口功能让右值指针初始化的shared_ptr

void AddObject(Object *o); 

类里面我保持set<shared_ptr<Object>>的对象。 由于我将从接收到的指针创建shared_ptr,我认为只将函数参数限制为右值指针,以确保用户不会删除我使用的指针。所以,我会改变函数声明:

void AddObject(Object* &&o); 

这样一个典型的使用将是:

AddObject(new Object()) 

防止用户不小心删除指针我抱。 我不想在界面中使用shared_ptr,因为用户不熟悉shared_ptr。 你认为我的建议是个好主意吗?

+0

“std :: unique_ptr”有什么问题? – AndyG

+0

那么同样的问题适用,如果我使用unique_ptr而不是 –

+0

我认为'unique_ptr'使它在界面中更加明显。另外,'move'语义已经与传递它们并行,所以'std :: move'一个'unique_ptr'是很自然的,但对于'std :: move'原始指针来说真的很奇怪。 – AndyG

回答

0

我认为这是一个坏主意。我确信有一个原因,为什么shared_ptr c-tor获取原始指针被标记为显式而不是使用r值。在我看来,最好教会用户一次关于智能指针,或者至少教导他们如何使用make_shared/make_unique(它们更安全,并且在make_shared的情况下更高效,顺便说一下)。

顺便说一句,为什么shared_ptr而不是unique_ptr

另外,为什么set?即使你想确保你只保留一次指针,并且每次搜索vector在代码中看起来都不够自然,我没有看到有理由保持指针的排序而不是使用unordered_set

0

首先,这种方法不会阻止用户删除指针。考虑这个例子

auto obj = new Object(); 
    AddObject(std::move(obj)); 
    delete obj; 

其次,调用newshared_ptr创作应尽可能少之间步骤的数量。如果在AddObject之内发生任何事情,它可以创建shared_ptr之前,该对象将永远不会被删除。

如果AddObject()有更多参数,则同样适用。如果构建这些失败,你会泄漏内存。

void AddObject(Object* &&o, SomeOtherObject* x); 

    AddObject(new Object(), xx()); // if xx() throws, memory leak will occur 

理想情况下,你会“包装”对象创建为shared_ptr建设:

void AddObject(std::shared_ptr<Object> o); 

    AddObject(std::make_shared<Object>()); 
+0

你的第一个例子确实显示了用户如何删除提供的指针,但它非常明确,只有恶意用户才会这样做。 –

0

下列方法之一可以解决你的问题。

  1. 您可能会附加更多关于AddObject的评论,告诉用户删除他们添加的指针是不被允许的。这已经足够了。
  2. 或者,你也可以让Object继承自一个基类,该基类有一个私有的析构函数和一个名为destroyByOwner的方法。