听说auto_ptr
在C ++ 11中已弃用。这是什么原因呢?
此外,我想知道的区别auto_ptr
和shared_ptr
。
Answers:
直接替换为auto_ptr
(或无论如何最接近的东西)unique_ptr
。就“问题”而言,它非常简单:auto_ptr
在分配所有权时转移所有权。unique_ptr
也转让所有权,但是由于移动语义的编纂和右值引用的神奇性,它可以更自然地做到这一点。它还可以更好地与标准库的其余部分“匹配”(尽管公平地说,这部分要归功于库的其余部分进行了更改,以适应移动语义而不是始终需要复制)。
名称更改(IMO)也很受欢迎- auto_ptr
并没有真正告诉您它试图实现自动化的目的,而是unique_ptr
对所提供内容的合理描述(如果简洁)。
auto_ptr
名称的注释:auto暗示auto就像auto variable一样,它表示auto_ptr
要这样做的一件事:销毁其析构函数中的托管资源(当它超出范围时)。
auto_ptr
:open-std.org/jtc1/sc22/wg21/docs/papers/2005/…–
std::sort
没有专门的unique_ptr
。相反,它被重新指定为从不复制。所以,auto_ptr
实际上不符合现代工作sort
。但是C ++ 98/03 sort
只是此处的示例算法: 任何假定复制语法具有复制语义的通用算法(由std提供或由用户编写),如果与一起使用auto_ptr
,可能会出现运行时错误,因为auto_ptr
静默移动与副本语法。问题远不止于此sort
。
我发现现有的答案很好,但是从指针的角度来看。IMO,一个理想的答案应该具有用户/程序员的观点答案。
首先第一件事(正如杰里·科芬在回答中所指出的)
shared_ptr: 如果您担心释放资源/内存,并且有多个功能可能正在使用对象AT-DIFFERENT次,那么请使用shared_ptr。
通过“时差”,可以考虑将对象-ptr存储在多个数据结构中并随后进行访问的情况。当然,多线程是另一个示例。
unique_ptr:如果您所关心的只是释放内存,并且对对象的访问是SEQUENTIAL,那么请使用unique_ptr。
我所说的SEQUENTIAL是指在任何时候都可以从一个上下文访问对象。例如,创建者创建后立即使用的对象。创建对象后,将其存储在FIRST数据结构中。然后,要么在ONE数据结构之后销毁对象,要么将其移动到SECOND数据结构。
从这一行,我将共享/唯一的_ptr称为智能指针。(由于其设计中的缺陷,auto_ptr也是智能指针BUT,对此已不推荐使用,我想在下一行中指出,不应将它们与智能指针归为一类。)
关于为什么不赞成使用auto_ptr而使用智能指针的一个最重要的原因是 赋值语义。 如果不是出于这个原因,他们会在auto_ptr中添加移动语义的所有新优点,而不是不赞成使用。由于分配语义是最不喜欢的功能,因此他们希望该功能消失,但是由于编写了使用该语义的代码(标准委员会无法更改),因此他们不得不放弃auto_ptr而不是修改它。
通过链接:http : //www.cplusplus.com/reference/memory/unique_ptr/operator=/
unqiue_ptr支持的作业类型
来自:http : //www.cplusplus.com/reference/memory/auto_ptr/operator=/
auto_ptr支持的分配类型
现在说出为什么如此不喜欢副本分配本身的原因,我有这样一个理论:
意外的行为确实令人讨厌,因此对auto_ptr也不喜欢。
(对于3.1415926536%的有意要转让所有权的程序员,C ++ 11给了他们std :: move(),这对于所有打算阅读和维护代码的实习生来说,他们的意图都非常清楚。)
auto_ptr
值指向同一对象(因为它们不赋予共享所有权,因此第一个死亡的值将使另一个值具有致命的遗产;这在unique_ptr
用法上也是如此),能否建议您打算使用什么值?剩余所有使用量的96.8584073465%?
*a=*b;
这里只有b的值被复制到a。我希望a和b的所有权仍然是同一个人。您提到的所有权将被转移。会怎么样?
auto_ptr
对象本身。赋予/从其指向的值进行赋值不会影响所有权,也不会与所有权相关。希望您还没有使用auto_ptr
?
还有另一种解释差异的看法。
从功能上讲,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
成员,则release
对实例进行复制将使要复制的实例中的指针成为一个怪异且危险的语义,因为通常复制某些内容不会对其进行修改。对于类/结构作者,在进行不变式和状态推理时,很容易忽略指针的释放,因此偶然地尝试在null或没有预期的对指针数据的访问/所有权的情况下取消引用智能指针。
auto_ptr不能在STL容器中使用,因为它的复制构造函数不满足容器CopyConstructible的要求。unique_ptr没有实现复制构造函数,因此容器使用其他方法。unique_ptr可以在容器中使用,并且在std算法中比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