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

时间:2009-08-04 12:58:58

标签: c++ stl boost shared-ptr auto-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 ?


修改:

  1. 因此,在回答“我能否安全地将auto_ptr替换为上述代码中的shared_ptr”时,答案是肯定的 - 不过我会受到轻微的影响。
  2. auto_ptr最终被标记为折旧并且我们转移到std::shared_ptr时,我们需要彻底测试我们的代码以确保我们遵守不同的所有权语义。

3 个答案:

答案 0 :(得分:35)

auto_ptrshared_ptr解决了完全不同的问题。一个不会取代另一个。

auto_ptr是实现RAII语义的指针的瘦包装器,因此即使面临异常,资源也总是被释放。 auto_ptr根本不执行任何引用计数等,它在创建副本时不会使多个指针指向同一个对象。事实上,它是非常不同的。 auto_ptr是赋值运算符修改对象的少数几个类之一。考虑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

注意如何执行

y = x;

不仅修改y而且修改x。

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

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

答案 1 :(得分:14)

其他人已经回答了为什么此代码使用auto_ptr代替shared_ptr的原因。解决您的其他问题:

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

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

此外,还有其他原因可以考虑使用auto_ptr代替shared_ptr吗?您是否认为将来有shared_ptr的问题?

就个人而言,我不会使用auto_ptr。复制删除太不直观了。 Herb Sutter seems to agree。切换到scoped_ptrunique_ptrshared_ptr应该没有任何问题。具体来说,如果您不关心引用计数开销,shared_ptr应该是替代品。如果您未使用scoped_ptr的所有权转让功能,则auto_ptr是替代品。如果您使用的是转让所有权,那么unique_ptr几乎是替代品,除非您需要明确调用move来转让所有权。有关示例,请参阅here

答案 2 :(得分:1)

auto_ptr是我使用的唯一一种智能指针。我使用它是因为我不使用Boost,因为我通常更喜欢我的业务/面向应用程序的类 定义删除语义和顺序,而不是依赖 智能指针的集合或个人。