为什么使用std::auto_ptr<>
标准容器是错误的?
随着新标准的出现(以及某些编译器中已有的部件),新类型std::unique_ptr
应该是替代品std::auto_ptr
.
它们的用法是否完全重叠(因此我可以对我的代码进行全局查找/替换(不是我会这样做,但如果我这样做))或者我应该注意一些在阅读文档时不明显的差异?
此外,如果它是一个直接替代品(为什么给它一个新的名称),而不仅仅是改善std::auto_ptr
.
我听说auto_ptr
在C++ 11中被弃用了.这是什么原因?
此外,我想知道的区别auto_ptr
和shared_ptr
.
我对unique_ptr和rvalue move哲学很困惑.
假设我们有两个集合:
std::vector<std::auto_ptr<int>> autoCollection;
std::vector<std::unique_ptr<int>> uniqueCollection;
Run Code Online (Sandbox Code Playgroud)
现在我希望以下内容失败,因为没有人知道算法在内部做了什么,也许还在制作内部数据透视副本等,从而剥夺了auto_ptr的所有权:
std::sort(autoCollection.begin(), autoCollection.end());
Run Code Online (Sandbox Code Playgroud)
我明白了 并且编译器正确地不允许这种情况发生.
但后来我这样做:
std::sort(uniqueCollection.begin(), uniqueCollection.end());
Run Code Online (Sandbox Code Playgroud)
这编译.我不明白为什么.我不认为unique_ptrs可以复制.这是否意味着不能采用枢轴值,因此排序效率较低?或者这个转轴实际上是一个移动,实际上和auto_ptrs的集合一样危险,编译器应该不允许这样做?
我想我错过了一些重要的信息,所以我急切等待有人给我提供啊哈!时刻.
标题几乎总结了我的问题.为什么不能执行以下操作来检查空指针?
auto_ptr<char> p( some_expression );
// ...
if ( !p ) // error
Run Code Online (Sandbox Code Playgroud)
必须这样做:
if ( !p.get() ) // OK
Run Code Online (Sandbox Code Playgroud)
为什么auto_ptr<T>
不简单operator!()
定义?
当尝试使用auto_ptr
带有forward-declaration声明的类型时,如下所示:
class A;
...
std::auto_ptr<A> a;
Run Code Online (Sandbox Code Playgroud)
A
没有调用析构函数(显然,因为auto_ptr
内部delete
的底层指针和不完整类型的析构函数不能被调用).
但是,相同的代码工作正常,并在使用时调用析构函数std::shared_ptr
而不是std::auto_ptr
.怎么解释?
与使用原始指针的类似(但不限于)某些高级技术相比,每个智能指针的等效用途是什么?
我的理解很少,但我可以收集到:
std::shared_ptr::reset
底层时deallocator
.std::shared_ptr
不增加引用计数的子类型,当其父级std::shared_ptr
不再存在时无效.可能会返回无效的引用.使用前请务必检查.RAW指针等效示例
引用计数,缓存实现: std::map<std::string, std::pair<long, BITMAP*> > _cache;
拥有所有权的单身人士:
class Keyboard {
public:
//...
static Keyboard* CreateKeyboard();
~Keyboard();
//...
private:
//...
Keyboard();
static Keyboard* _instance;
//...
};
Run Code Online (Sandbox Code Playgroud)
聚合容器,无所有权:空间分区图和树,迭代容器等.
复合容器,所有权:大型对象.
- 编辑 -
在我工作的时候,我遇到了一个有趣的案例,DeadMG指出智能指针应该被用作简单的抽象来处理资源管理; 那些在声明点无法在堆上创建但必须在以后创建的文件范围对象呢?
我们已经转移到使用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
,我们需要彻底测试我们的代码以确保我们遵守不同的所有权语义.