我不完全理解
unique_ptr
相对于auto_ptr
的好处,或者我还没有完全相信为什么我们需要使用unique_ptr
。
我看到以下差异。
1)
unique_ptr
支持数组,因此 unique_ptr
析构函数为数组调用 delete []
,而 auto_ptr
析构函数仅调用 delete
。
2) 遇到
std::move()
时,必须使用unique_ptr
,而不是直接复制。但是 std::move()
能给我们带来什么好处呢?我将尝试如下解释。
auto_ptr <int> p1 (new int);
auto_ptr <int> p2 = p1; // Now p1 is NULL and p2 exists with value of p1
unique_ptr <int> p1 (new int);
unique_ptr <int> p2 = std::move(p1); // Now p1 is NULL and p2 exists with value of p1
那么我们将获得什么优势?
3)我在网上看到
unique_ptr
可以用在容器中。但如果我理解正确的话,这并不是unique_ptr
的伟大之处。容器函数语义发生了变化,因此现在,复制无法在容器函数内部完成。但这是unique_ptr
的伟大之处吗?既然容器功能都变了,为什么我们不能在容器中使用auto_ptr
呢?
首先,
auto_ptr
有神奇的构造函数,比如auto_ptr(auto_ptr &other) {...}
,其行为如下:
other
实例复制。other
实例。现在的编译器支持
std::move(...)
,因此不需要实际上“移动”的“复制式”构造函数,但为了支持旧代码,auto_ptr
保持不变,而是被弃用(稍后删除)。
unique_ptr
迫使您明确转让所有权,因此它在代码中是可见且清晰的。使用auto_ptr
,很容易获得所有权的静默转移,并且在阅读代码时,并不总是清楚所有权是否已转移,如果是,则不清楚它是代码作者的意图还是一个错误!当您看到 unique_ptr
与 std::move
一起使用时,很明显其意图是转移所有权。
unique_ptr
正确支持移动语义,因此它只允许从临时对象和移动对象(即rvalues)进行所有权转移。容器可以检测类型是否“移动感知”并采取适当的行动。 auto_ptr
不知道移动语义,并且会从左值或右值转移所有权,因此容器认为它是一个普通的可复制对象,但它的行为并不像一个对象,因为它在复制时修改了其源。
小心使用时,auto_ptr
很有用,但很容易误用它并编写危险的代码。是时候让它死去了。 unique_ptr
支持auto_ptr
可以做的一切,但默认情况下是安全的(你必须更加努力地使用它),并且还具有额外的功能,例如自定义删除器和数组支持。