为什么auto_ptr被弃用?
我听说在C ++ 11中不推荐使用auto_ptr
。 这是什么原因?
另外我想知道auto_ptr
和shared_ptr
之间的区别。
auto_ptr
的直接replace(或者最接近的一个)是unique_ptr
。 就“问题”而言,这非常简单: auto_ptr
在分配时转移所有权。 unique_ptr
也转让所有权,但是由于移动语义的编码和右值引用的魔力,它可以更自然地做到这一点。 它也与标准库的其余部分“相配”的好得多(尽pipe公平地说,其中一些是由于库的其余部分改变以适应移动语义而不是总是需要复制)。
名称上的变化也是(IMO)的一个值得欢迎的事情 – auto_ptr
并没有真正告诉你什么它试图自动化,而unique_ptr
是一个相当合理(如果简洁)的说明。
我发现现有的答案很好,但从PoV的指针。 海事组织,一个理想的答案应该有用户/程序员的angular度来回答。
第一件事情是第一件事(正如Jerry Coffin在他的回答中指出的那样)
- 根据情况,auto_ptr可以被shared_ptr或unique_ptr取代
shared_ptr:如果您担心释放资源/内存,并且您有多个可能在不同时间使用该对象的函数,请使用shared_ptr。
通过DIFFERENT-Times,考虑一下这样一种情况,object-ptr被存储在多个数据结构中,随后被访问。 当然multithreading就是另外一个例子。
unique_ptr:如果你所关心的是释放内存,访问对象是SEQUENTIAL,那么去unique_ptr。
通过SEQUENTIAL,我的意思是,任何时候都可以从一个上下文访问对象。 例如,创build者创build并立即使用的对象。 在创build之后,对象被存储在FIRST数据结构中。 然后,在ONE数据结构之后,该对象被销毁,或者被移动到SECOND数据结构。
从这一行,我将引用共享/唯一的_ptr作为智能指针。 (auto_ptr也是智能指针,但是因为它的devise上存在缺陷,所以我们会在下一行中指出它们,不应该用智能指针来分组)。
关于为什么auto_ptr不赞成使用智能指针的一个最重要的原因是赋值语义如果不是这个原因,他们会将所有新的移动语义的好东西添加到auto_ptr而不是废弃它。 由于赋值语义是最不喜欢的function,所以他们希望这个function消失,但是由于使用该语义编写的代码(哪个标准委员会不能改变),他们不得不放弃auto_ptr,而不是修改它。
从链接: http : //www.cplusplus.com/reference/memory/unique_ptr/operator=/
unqiue_ptr支持的作业种类
- 移动作业(1)
- 分配空指针(2)
- types转换作业(3)
- 复制作业(删除!)(4)
来自: http : //www.cplusplus.com/reference/memory/auto_ptr/operator=/
auto_ptr支持的分配types
- 复制任务(4) 罪魁祸首
为什么为什么副本任务本身是如此不喜欢,我有这样的理论:
- 并非所有程序员都阅读书籍或标准
- 面对它的auto_ptr,承诺你拥有该对象
- auto_ptr的little- *(双关语)子句,它不被所有程序员读取,允许将一个auto_ptr赋值给另一个auto_ptr,并转移所有权。
- 研究表明,这种行为的目的是3.1415926535%的所有使用,而在其他情况下意外。
意想不到的行为是真的不喜欢,因此不喜欢auto_ptr。
(对于3.1415926536有意转移所有权的程序员,%C ++ 11给了他们std :: move(),这使得他们对所有将要读取和维护代码的实习生都清楚了。
shared_ptr
可以存储在容器中。 auto_ptr
不能。
BTW unique_ptr
实际上是直接的auto_ptr
replace,它结合了std::auto_ptr
和boost::scoped_ptr
的最佳特性。
还有一个解释的区别….
在function上,C ++ 11的std::unique_ptr
是“固定的” std::auto_ptr
:它们都适用于 – 在执行期间的任何时间点 – 应该有一个指向对象的智能指针所有者。
关键的区别在于复制构造或从另一个未到期的智能指针分配,如下面的=>
行所示:
std::auto_ptr<T> ap(...); std::auto_ptr<T> ap2(get_ap_to_T()); // take expiring ownership => std::auto_ptr<T> ap3(ap); // take un-expiring ownership ala ap3(ap.release()); ap->xyz; // oops... can still try to use ap, expecting it to be non-NULL std::unique_ptr<T> up(...); std::unique_ptr<T> up2(get_up_to_T()); // take expiring ownership => std::unique_ptr<T> up3(up); // COMPILE ERROR: can't take un-expiring ownership => std::unique_ptr<T> up4(std::move(up)); // EXPLICIT code allowed => std::unique_ptr<T> up4(up.release()); // EXPLICIT code allowed
以上, ap3
悄悄地“窃取”了*ap
所有权,将ap
设置为nullptr
,问题在于,如果程序员没有经过安全考虑,问题就会变得太容易。
例如,如果一个class
/ struct
有一个std::auto_ptr
成员,那么创build一个实例的副本将release
被复制的实例的指针:这是奇怪的和危险的混淆语义,因为通常复制东西不会修改它。 类/结构作者很容易在推理不变和状态的时候忽略指针的释放,并因此偶然地试图在空值时解引用智能指针,或者只是没有期望指向数据的访问/所有权。
auto_ptr不能在STL容器中使用,因为它的拷贝构造函数不符合容器copyconstructable的要求。 unique_ptr不实现复制构造函数,因此容器使用替代方法。 unique_ptr可以在容器中使用,对于stdalgorithm和shared_ptr则更快。
#include <iostream> #include <type_traits> #include <vector> #include <memory> using namespace std; int main() { cout << boolalpha; cout << "is_copy_constructible:" << endl; cout << "auto_ptr: " << is_copy_constructible< auto_ptr<int> >::value << endl; cout << "unique_ptr: " << is_copy_constructible< unique_ptr<int> >::value << endl; cout << "shared_ptr: " << is_copy_constructible< shared_ptr<int> >::value << endl; vector<int> i_v; i_v.push_back(1); cout << "i_v=" << i_v[0] << endl; vector<int> i_v2=i_v; cout << "i_v2=" << i_v2[0] << endl; vector< unique_ptr<int> > u_v; u_v.push_back(unique_ptr<int>(new int(2))); cout << "u_v=" << *u_v[0] << endl; //vector< unique_ptr<int> > u_v2=u_v; //will not compile, need is_copy_constructible == true vector< unique_ptr<int> > u_v2 =std::move(u_v); // but can be moved cout << "u_v2=" << *u_v2[0] << " length u_v: " <<u_v.size() << endl; vector< shared_ptr<int> > s_v; shared_ptr<int> s(new int(3)); s_v.push_back(s); cout << "s_v=" << *s_v[0] << endl; vector< shared_ptr<int> > s_v2=s_v; cout << "s_v2=" << *s_v2[0] << endl; vector< auto_ptr<int> > a_v; //USAGE ERROR return 0; } >cxx test1.cpp -o test1 test1.cpp: In function âint main()â: test1.cpp:33:11: warning: âauto_ptrâ is deprecated (declared at /apps/hermes/sw/gcc/gcc-4.8.5/include/c++/4.8.5/backward/auto_ptr.h:87) [-Wdeprecated-declarations] vector< auto_ptr<int> > a_v; //USAGE ERROR ^ >./test1 is_copy_constructible: auto_ptr: false unique_ptr: false shared_ptr: true i_v=1 i_v2=1 u_v=2 s_v=3 s_v2=3