什么时候会使用 std::auto_ptr 而不是 boost::shared_ptr?

发布于 2024-07-30 01:04:04 字数 1006 浏览 5 评论 0原文

我们几乎已经在所有代码中使用 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 时遇到任何问题将来?


编辑:

  1. 因此,在回答“我可以安全地将上面代码中的 auto_ptr 替换为 shared_ptr”时,答案是肯定的 - 但是我会性能受到轻微影响。
  2. 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:

  1. So in answer to "can I safely replace auto_ptr with shared_ptr in the above code", the answer is yes - however I'll take a small performance hit.
  2. When auto_ptr is eventually marked as depreciated and we move over to std::shared_ptr, we'll need to thoroughly test our code to make sure we're abiding by the different ownership semantics.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千纸鹤带着心事 2024-08-06 01:04:04

auto_ptrshared_ptr 解决完全不同的问题。 其中之一不能取代另一个。

auto_ptr 是一个围绕指针的薄包装器,用于实现 RAII 语义,以便即使遇到异常,资源也总是会被释放。 auto_ptr 根本不执行任何引用计数之类的操作,它在创建副本时不会使多个指针指向同一个对象。 事实上,这是非常不同的。 auto_ptr 是赋值运算符修改 source 对象的少数类之一。 考虑一下 auto_ptr wikipedia 页面 中的这个无耻插件:

int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;

y = x;

cout << x.get() << endl; // Print NULL
cout << y.get() << endl; // Print non-NULL address i

注意执行

y = x;

不仅会修改 y,还会修改 x。

boost::shared_ptr 模板可以轻松处理指向同一对象的多个指针,并且该对象仅在最后一次引用超出范围后才会被删除。 此功能在您的场景中没有用,您的场景(尝试)实现 Singleton。 在您的场景中,总是有 0 个引用到 1 个对该类的唯一对象的引用(如果有)。

本质上,auto_ptr对象和shared_ptr对象具有完全不同的语义(这就是为什么你不能在容器中使用前者,但使用后者就可以了),我确信希望您有良好的测试来捕获移植代码时引入的任何回归。 :-}

auto_ptr and shared_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:

int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;

y = x;

cout << x.get() << endl; // Print NULL
cout << y.get() << endl; // Print non-NULL address i

Note how executing

y = x;

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 and shared_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. :-}

红ご颜醉 2024-08-06 01:04:04

其他人已经回答了为什么此代码使用 auto_ptr 而不是 shared_ptr。 要解决您的其他问题:

我可以用什么/如何替换此实现?

使用 boost::scoped_ptrunique_ptr(Boost 和新的 C++ 标准)。 scoped_ptrunique_ptr 都提供严格的所有权(并且没有引用计数开销),并且它们避免了 auto_ptr 令人惊讶的复制时删除语义。

此外,还有其他原因让您考虑使用 auto_ptr 而不是 shared_ptr 吗? 您认为将来迁移到 shared_ptr 会出现任何问题吗?

就我个人而言,我不会使用 auto_ptr。 复制时删除太不直观了。 赫伯·萨特似乎同意。 切换到 scoped_ptrunique_ptrshared_ptr 应该不会有任何问题。 具体来说,如果您不关心引用计数开销,则 shared_ptr 应该是一个直接替代品。 如果您不使用 auto_ptr 的所有权转让功能,则 scoped_ptr 是一个直接替代品。 如果您使用所有权转让,那么 unique_ptr 几乎是一个直接替代品,只不过您需要显式调用 move 来转让所有权。 有关示例,请参阅此处

Others have answered why this code uses an auto_ptr instead of a shared_ptr. To address your other questions:

What/how I can replace this implementation?

Use either boost::scoped_ptr or unique_ptr (available in both Boost and the new C++ standard). Both scoped_ptr and unique_ptr provide strict ownership (and no reference counting overhead), andthey avoid the surprising delete-on-copy semantics of auto_ptr.

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?

Personally, I would not use an auto_ptr. Delete-on-copy is just too non-intuitive. Herb Sutter seems to agree. Switching to scoped_ptr, unique_ptr, or shared_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 using auto_ptr's transfer-of-ownership capabilities. If you are using transfer-of-ownership, then unique_ptr is almost a drop-in replacement, except that you need to instead explicitly call move to transfer ownership. See here for an example.

内心荒芜 2024-08-06 01:04:04

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文