我听说C++11中auto_ptr
已被弃用,这是什么原因?
另外,我想知道auto_ptr
和shared_ptr
的区别。
我听说C++11中auto_ptr
已被弃用,这是什么原因?
另外,我想知道auto_ptr
和shared_ptr
的区别。
auto_ptr
(或最接近的替代品)的是unique_ptr
。就“问题”而言,它相当简单:auto_ptr
在被分配时转移所有权。unique_ptr
也会转移所有权,但由于移动语义的规范化以及右值引用的神奇之处,可以更自然地进行转移。 它也与标准库的其他部分更加“匹配”(尽管公平地说,其中一些要归功于库的其余部分改变以适应移动语义而不总是需要复制)。auto_ptr
对尝试自动化的内容并没有提供太多信息,而unique_ptr
则是对所提供内容的一个相当合理(虽然简洁)的描述。auto_ptr
名称的注解:auto暗示了自动变量,它指的是auto_ptr
所做的一件事情:在其析构函数中(当其超出作用域时)销毁管理资源。 - Vincenzo Piiauto_ptr
的官方原因:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html#20.4.5%20-%20Class%20template%20auto_ptr - Howard Hinnantstd::sort
没有针对unique_ptr
的特化。相反,它被重新指定为永远不会复制。因此,现代的sort
实际上可以使用auto_ptr
。但是C++98/03的sort
只是这里的一个示例算法:任何假定复制语法具有复制语义的通用算法(std提供的或用户编写的)如果与auto_ptr
一起使用,可能会导致运行时错误,因为auto_ptr
使用复制语法静默地移动。这个问题比sort
要大得多。 - Howard Hinnant来源:http://www.cplusplus.com/reference/memory/auto_ptr/operator=/
auto_ptr支持的赋值类型
现在来谈谈为什么复制赋值本身如此不受欢迎,我有这个理论:
不良行为真的不受欢迎,因此不喜欢auto_ptr。
(对于那些刻意想要转移C++11赋予的所有权std::move()的3.1415926536%程序员,这使得他们的意图对于将来阅读和维护代码的实习生变得非常明确。)auto_ptr
值(因为它们不提供共享所有权,第一个死亡的将使另一个留下致命遗产;这也适用于unique_ptr
使用), 您能建议在剩余96.8584073465%的所有用法中打算使用什么吗? - Marc van Leeuwen*a=*b;
这里只是将b的值复制到a中。我希望a和b的所有权仍然属于同一人。你提到了所有权将被转移。那么它会是怎样的呢? - VINOTH ENERGETICauto_ptr
对象分配给自身。对/从其指向的值进行分配对所有权没有影响或相关性。我希望你现在不再使用auto_ptr
了? - underscore_dshared_ptr
可以存储在容器中,auto_ptr
则不行。
顺便说一句,unique_ptr
真正是 auto_ptr
的直接替代品,它结合了 std::auto_ptr
和 boost::scoped_ptr
的最佳特点。
std :: 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
静默地“窃取”了*ap
的所有权,并使 ap
设为 nullptr
。问题在于,这种情况很容易发生,程序员可能没有考虑到它的安全性。class
/struct
有一个std::auto_ptr
成员,则复制实例会从被复制的实例中释放指针:这是一种奇怪和危险的混淆语义,因为通常复制不会修改原实例。当类/结构的作者在推理不变量和状态时容易忽略指针的释放,因此意外地尝试在空指针上解引用智能指针,或者仅仅没有对指向数据的访问/所有权进行预期。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