我们已经转移到在所有代码中使用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
时,我们需要彻底测试我们的代码以确保我们遵守不同的所有权语义。 答案 0 :(得分:35)
auto_ptr
和shared_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_ptr
或unique_ptr
(可在Boost和新的C ++标准中使用)。 scoped_ptr
和unique_ptr
都提供严格的所有权(并且没有引用计数开销),并且它们避免了auto_ptr
令人惊讶的复制时删除语义。
此外,还有其他原因可以考虑使用auto_ptr
代替shared_ptr
吗?您是否认为将来有shared_ptr
的问题?
就个人而言,我不会使用auto_ptr
。复制删除太不直观了。 Herb Sutter seems to agree。切换到scoped_ptr
,unique_ptr
或shared_ptr
应该没有任何问题。具体来说,如果您不关心引用计数开销,shared_ptr
应该是替代品。如果您未使用scoped_ptr
的所有权转让功能,则auto_ptr
是替代品。如果您使用的是转让所有权,那么unique_ptr
几乎是替代品,除非您需要明确调用move
来转让所有权。有关示例,请参阅here。
答案 2 :(得分:1)
auto_ptr是我使用的唯一一种智能指针。我使用它是因为我不使用Boost,因为我通常更喜欢我的业务/面向应用程序的类 定义删除语义和顺序,而不是依赖 智能指针的集合或个人。