我有一个项目,我想更多地使用智能指针。总的来说,我在这个目标上取得了成功。但是,我遇到过一些我不确定“最佳实践”是什么的事情。
基本上我想从函数返回一个“指针”,但要求用户将其保存在智能指针中。不仅如此,我不想强制使用特定的智能指针(共享与范围)。
问题主要是似乎没有正确的方法将scoped_ptr
升级为shared_ptr
(这是我认为的理想解决方案)。我明白为什么他们不这样做,因为它会允许转让所有权,这可能导致像std::auto_ptr
那样的问题。
但是,对于这个案例来说,转让所有权似乎是一个好主意。所以我的想法是这样的:
// contrived example of factory pattern
std::auto_ptr<A> func() { return std::auto_ptr<A>(new A); }
这可以“正常”,因为scoped_ptr
和shared_ptr
的构造函数都取自std::auto_ptr
。
所以我的问题是,这是一个好习惯吗?有更好的解决方案吗?我能够想出的唯一真正的替代方法是使用模板模板作为返回值,如下所示:
// similar to above example
template <template <typename> class P>
P<A> func() { return P<A>(new A); }
实际上可以很好地工作,除了我认为需要一些工作才能让它与scoped_ptr
一起工作。
思想?
答案 0 :(得分:11)
使用std::auto_ptr
良好做法,事实上such example被建议
作者:Bjarne Stroustrup。
auto_ptr
的移动语义为您提供了正确的工具来处理它。
例如:
auto_ptr<Foo> make_foo()
{
return auto_ptr<Foo>(new Foo);
}
Foo *raw_pointer=make_foo().release();
shared_ptr<Foo> shared_pointer=make_foo();
auto_ptr<Foo> auto_pointer=make_foo();
如果您返回shared_ptr
,则无法使用auto_ptr
回退到正常指针。您可以将auto_ptr
升级为共享但不是其他方向。
另一个重点,shared_ptr
使用原子引用计数,这要慢得多
auto_ptr
做的那种简单而又完全有效的工作。
P.S。:scoped_ptr
只是版本auto_ptr
的版本 - 它是不可复制的
没有默认的构造函数。与auto_ptr
相比,它更像“不那么令人困惑”的shared_ptr
版本,而不是tr1。一般来说使用没有多大优势
scoped_ptr
超过auto_ptr
答案 1 :(得分:3)
如果你建立一个可以简单地返回指针的工厂。并且您工厂的用户可以自己决定如何以及在何处放置此指针。
如果您需要强制使用智能指针,则必须限制选择,因为您不希望它们使用“错误”指针。
所以boost :: shared_ptr。但最好将其定义为MyClassPtr或MyClass :: ptr。
仍然,工厂他们就像“新”。当我想要把新的结果放在std :: auto_ptr里面。但是当我不想要智能指针时,我不想被迫一直打电话给“释放”。
答案 2 :(得分:1)
使用C ++ 11,您应该能够使用std::unique_ptr
,因为其他智能指针类型具有采用std::unique_ptr
的构造函数。如果您维护此类资源的内部列表,那么您可能希望使用std::shared_ptr
。