什么时候会使用 std::auto_ptr 而不是 boost::shared_ptr?
我们几乎已经在所有代码中使用 boost::shared_ptr
,但是我们仍然有一些使用 std::auto_ptr
的孤立情况,包括单例类:
template < typename TYPE >
class SharedSingleton
{
public:
static TYPE& Instance()
{
if (_ptrInstance.get() == NULL)
_ptrInstance.reset(new TYPE);
return *_ptrInstance;
}
protected:
SharedSingleton() {};
private:
static std::auto_ptr < TYPE > _ptrInstance;
};
有人告诉我,有一个很好的理由为什么它没有成为 shared_ptr
,但我一生都无法理解为什么? 我知道 auto_ptr
最终将在下一个标准中被标记为已弃用,因此我想知道我可以用什么/如何替换此实现。
此外,还有其他原因让您考虑使用 auto_ptr
而不是 shared_ptr
吗?您是否发现迁移到 shared_ptr 时遇到任何问题将来?
编辑:
- 因此,在回答“我可以安全地将上面代码中的
auto_ptr
替换为shared_ptr
”时,答案是肯定的 - 但是我会性能受到轻微影响。 - 当
auto_ptr
最终被标记为已弃用并且我们转向std::shared_ptr
时,我们需要彻底测试我们的代码以确保我们遵守不同的规则所有权语义。
We've pretty much moved over to using boost::shared_ptr
in all of our code, however we still have some isolated cases where we use std::auto_ptr
, including singleton classes:
template < typename TYPE >
class SharedSingleton
{
public:
static TYPE& Instance()
{
if (_ptrInstance.get() == NULL)
_ptrInstance.reset(new TYPE);
return *_ptrInstance;
}
protected:
SharedSingleton() {};
private:
static std::auto_ptr < TYPE > _ptrInstance;
};
I've been told that there's a very good reason why this hasn't been made a shared_ptr
, but for the life of me I can't understand why? I know that auto_ptr
will eventually get marked as depreciated in the next standard, so I'd like to know what/how I can replace this implementation.
Also, are there any other reasons why you'd consider using an auto_ptr
instead of a shared_ptr
? And do you see any problems moving to shared_ptr in the future?
Edit:
- So in answer to "can I safely replace
auto_ptr
withshared_ptr
in the above code", the answer is yes - however I'll take a small performance hit. - When
auto_ptr
is eventually marked as depreciated and we move over tostd::shared_ptr
, we'll need to thoroughly test our code to make sure we're abiding by the different ownership semantics.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
auto_ptr
和shared_ptr
解决完全不同的问题。 其中之一不能取代另一个。auto_ptr
是一个围绕指针的薄包装器,用于实现 RAII 语义,以便即使遇到异常,资源也总是会被释放。auto_ptr
根本不执行任何引用计数之类的操作,它在创建副本时不会使多个指针指向同一个对象。 事实上,这是非常不同的。auto_ptr
是赋值运算符修改 source 对象的少数类之一。 考虑一下 auto_ptr wikipedia 页面 中的这个无耻插件:注意执行
不仅会修改 y,还会修改 x。
boost::shared_ptr
模板可以轻松处理指向同一对象的多个指针,并且该对象仅在最后一次引用超出范围后才会被删除。 此功能在您的场景中没有用,您的场景(尝试)实现 Singleton。 在您的场景中,总是有 0 个引用到 1 个对该类的唯一对象的引用(如果有)。本质上,auto_ptr对象和shared_ptr对象具有完全不同的语义(这就是为什么你不能在容器中使用前者,但使用后者就可以了),我确信希望您有良好的测试来捕获移植代码时引入的任何回归。 :-}
auto_ptr
andshared_ptr
solve entirely different problems. One does not replace the other.auto_ptr
is a thin wrapper around pointers to implement RAII semantics, so that resources are always released, even when facing exceptions.auto_ptr
does not perform any reference counting or the like at all, it does not make multiple pointers point to the same object when creating copies. In fact, it's very different.auto_ptr
is one of the few classes where the assignment operator modifies the source object. Consider this shameless plug from the auto_ptr wikipedia page:Note how executing
modifies not only y but also x.
The
boost::shared_ptr
template makes it easy to handle multiple pointers to the same object, and the object is only deleted after the last reference to it went out of scope. This feature is not useful in your scenario, which (attempts to) implement a Singleton. In your scenario, there's always either 0 references to 1 reference to the only object of the class, if any.In essence,
auto_ptr
objects andshared_ptr
objects have entirely different semantics (that's why you cannot use the former in containers, but doing so with the latter is fine), and I sure hope you have good tests to catch any regressions you introduced while porting your code. :-}其他人已经回答了为什么此代码使用
auto_ptr
而不是shared_ptr
。 要解决您的其他问题:我可以用什么/如何替换此实现?
使用
boost::scoped_ptr
或unique_ptr
(Boost 和新的 C++ 标准)。scoped_ptr
和unique_ptr
都提供严格的所有权(并且没有引用计数开销),并且它们避免了auto_ptr
令人惊讶的复制时删除语义。此外,还有其他原因让您考虑使用
auto_ptr
而不是shared_ptr
吗? 您认为将来迁移到shared_ptr
会出现任何问题吗?就我个人而言,我不会使用
auto_ptr
。 复制时删除太不直观了。 赫伯·萨特似乎同意。 切换到scoped_ptr
、unique_ptr
或shared_ptr
应该不会有任何问题。 具体来说,如果您不关心引用计数开销,则shared_ptr
应该是一个直接替代品。 如果您不使用auto_ptr
的所有权转让功能,则scoped_ptr
是一个直接替代品。 如果您使用所有权转让,那么unique_ptr
几乎是一个直接替代品,只不过您需要显式调用move
来转让所有权。 有关示例,请参阅此处。Others have answered why this code uses an
auto_ptr
instead of ashared_ptr
. To address your other questions:What/how I can replace this implementation?
Use either
boost::scoped_ptr
orunique_ptr
(available in both Boost and the new C++ standard). Bothscoped_ptr
andunique_ptr
provide strict ownership (and no reference counting overhead), andthey avoid the surprising delete-on-copy semantics ofauto_ptr
.Also, are there any other reasons why you'd consider using an
auto_ptr
instead of ashared_ptr
? And do you see any problems moving toshared_ptr
in the future?Personally, I would not use an
auto_ptr
. Delete-on-copy is just too non-intuitive. Herb Sutter seems to agree. Switching toscoped_ptr
,unique_ptr
, orshared_ptr
should offer no problems. Specifically,shared_ptr
should be a drop-in replacement if you don't care about the reference counting overhead.scoped_ptr
is a drop-in replacement if you aren't usingauto_ptr
's transfer-of-ownership capabilities. If you are using transfer-of-ownership, thenunique_ptr
is almost a drop-in replacement, except that you need to instead explicitly callmove
to transfer ownership. See here for an example.auto_ptr 是我使用的唯一一种智能指针。 我使用它是因为我不使用 Boost,并且因为我通常更喜欢我的面向业务/应用程序的类而不是显式地
定义删除语义和顺序,而不是依赖于
智能指针的集合或单个智能指针。
auto_ptr is the only kind of smart pointer I use. I use it because I don't use Boost, and because I generally prefer my business/application-oriented classes to explicitly
define deletion semantics and order, rather than depend on
collections of, or individual, smart pointers.