我听说auto_ptr
在 C++11 中被弃用了。这是什么原因?
我也想知道 和 之间的auto_ptr
区别shared_ptr
。
我听说auto_ptr
在 C++11 中被弃用了。这是什么原因?
我也想知道 和 之间的auto_ptr
区别shared_ptr
。
的直接替代品auto_ptr
(或最接近的替代品)是unique_ptr
. 就“问题”而言,它非常简单:auto_ptr
在分配所有权时转移所有权。unique_ptr
也转移所有权,但由于移动语义的编码和右值引用的魔力,它可以更自然地做到这一点。它也更好地“适合”标准库的其余部分(尽管公平地说,其中一些要归功于库的其余部分进行了更改以适应移动语义,而不是总是需要复制)。
名称的更改也是(IMO)一个受欢迎的更改 -auto_ptr
并没有真正告诉您它试图自动化的内容,而是unique_ptr
对所提供内容的相当合理(如果简洁)的描述。
我发现现有的答案很好,但来自指针的 PoV。IMO,一个理想的答案应该有用户/程序员的观点答案。
首先第一件事(正如杰里·科芬在他的回答中指出的那样)
shared_ptr : 如果您担心资源/内存的释放,并且如果您有多个函数可以使用对象 AT-DIFFERENT 次,那么请使用 shared_ptr。
通过 DIFFERENT-Times,想想 object-ptr 存储在多个数据结构中并稍后访问的情况。多线程,当然是另一个例子。
unique_ptr :如果您只关心释放内存,并且对对象的访问是连续的,那么请使用 unique_ptr。
我的意思是,在任何时候都可以从一个上下文访问对象。例如,创建者创建并在创建后立即使用的对象。创建后,对象存储在FIRST数据结构中。然后对象要么在 ONE 数据结构之后被销毁,要么被移动到SECOND数据结构。
从这一行开始,我将共享/唯一 _ptr 称为智能指针。(auto_ptr 也是智能指针,但由于其设计存在缺陷,因此它们已被弃用,我想我将在下一行中指出,它们不应与智能指针分组。)
关于为什么不推荐使用 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(),这让所有将要阅读和维护代码的实习生清楚地知道他们的意图。)
shared_ptr
可以存放在容器内。 auto_ptr
不能。
BTWunique_ptr
真的是直接auto_ptr
替代品,它结合了std::auto_ptr
和的最佳特性boost::scoped_ptr
。
另一种解释差异的方法......
从功能上讲,C++11std::unique_ptr
是“固定的” std::auto_ptr
:它们都适用于 - 在执行期间的任何时间点 - 指向对象应该有一个智能指针所有者。
关键的区别在于从另一个未到期的智能指针复制构造或赋值,如下=>
行所示:
std::auto_ptr<T> ap(new T{...}); // OK - alloc/construct, up owns
...or...
std::auto_ptr<T> ap(get_ap_to_T()); // OK - take expiring ownership
...then...
=> std::auto_ptr<T> ap2(ap); // take un-expiring ownership ala ap3(ap.release());
ap->xyz; // oops... tried to use ap, expecting it to be non-NULL
// --------------------------------------------------------------
std::unique_ptr<T> up(new T{...}); // OK - alloc/construct, up owns
...or...
std::unique_ptr<T> up = std::make_unique<T>(...); // OK too
...or...
std::unique_ptr<T> up(get_up_to_T()); // OK - take expiring ownership
...then...
=> std::unique_ptr<T> up2(up); // COMPILE ERROR: can't take un-expiring ownership
=> std::unique_ptr<T> up2(std::move(up)); // EXPLICIT code allowed
=> std::unique_ptr<T> up2(up.release()); // EXPLICIT code allowed
上面,ap3
auto_ptr
悄悄地“窃取”了 的所有权,设置为 a ,问题是这很容易发生,而程序员没有考虑过它的安全性*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