Ala*_*lan 17 c++ boost stl auto-ptr 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;
};
Run Code Online (Sandbox Code Playgroud)
我被告知有一个很好的理由说明为什么没有这个shared_ptr
,但对于我的生活,我不明白为什么?我知道auto_ptr
最终会在下一个标准中被标记为折旧,所以我想知道我可以用什么/如何替换这个实现.
另外,你有没有其他原因考虑使用auto_ptr
而不是shared_ptr
?你认为将来有什么问题转移到shared_ptr吗?
编辑:
auto_ptr
与shared_ptr
在上面的代码",答案是肯定的-但我会带一个小的性能损失.auto_ptr
最终标记为折旧并且我们转向时std::shared_ptr
,我们需要彻底测试我们的代码以确保我们遵守不同的所有权语义.Fre*_*abe 35
auto_ptr
并shared_ptr
解决完全不同的问题.一个不能取代另一个.
auto_ptr
是一个实现RAII语义的指针的瘦包装器,因此即使在面临异常时也始终释放资源.auto_ptr
根本不执行任何引用计数等,它在创建副本时不会使多个指针指向同一个对象.事实上,它是非常不同的.auto_ptr
是赋值运算符修改源对象的少数几个类之一.考虑auto_ptr维基百科页面中的这个无耻插件:
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
Run Code Online (Sandbox Code Playgroud)
注意如何执行
y = x;
Run Code Online (Sandbox Code Playgroud)
不仅修改y而且修改x.
该boost::shared_ptr
模板可以轻松处理指向同一对象的多个指针,并且只有在最后一次引用它超出范围后才删除该对象.此功能在您的场景中没有用,它(尝试)实现Singleton.在您的场景中,如果有的话,总是0引用1引用该类的唯一对象.
本质上,auto_ptr
对象和shared_ptr
对象具有完全不同的语义(这就是为什么你不能在容器中使用前者,但是使用后者这样做很好),我确信希望你有很好的测试来捕获你在移植代码时引入的任何回归.: - }
Jos*_*ley 14
其他人已经回答了为什么这个代码使用auto_ptr
而不是a shared_ptr
.解决您的其他问题:
我可以用什么/如何替换这个实现?
使用boost::scoped_ptr
或者unique_ptr
(在Boost和新的C++标准中都有).双方scoped_ptr
并unique_ptr
提供严格的所有权(没有引用计数的开销),andthey避免令人惊讶的删除上拷贝语义auto_ptr
.
另外,你有没有其他原因考虑使用auto_ptr
而不是shared_ptr
?你认为shared_ptr
将来有什么问题吗?
就个人而言,我不会使用auto_ptr
.复制删除太不直观了. Herb Sutter似乎同意.切换到scoped_ptr
,unique_ptr
或者shared_ptr
应该没有问题.具体而言,shared_ptr
如果您不关心引用计数开销,应该是替代品. scoped_ptr
如果您不使用auto_ptr
所有权转让功能,则可以直接替换.如果您使用的是所有权转让,那么unique_ptr
除了您需要明确调用move
转移所有权之外,它几乎是替代品.请看这里的例子.