我被告知:
u = nullptr
删除unique_ptr u
指向的对象;使u
为空
u.release()
放弃对指针u
的控制;返回指针u
的控制,并使u
为空;
AFAIK,unique_ptr::release()
不应释放分配的内存,因为它是为转移所有权而发明的。
因此,我一直认为上面u
中提到的“使u.release()
为空”与u = nullptr
不同。也许u
本身不是null,只有get.()
返回nullptr
,如cpprefence中所述。
但是我得到了
#include <memory>
#include <iostream>
using namespace std;
int main()
{
unique_ptr<string> p1(new string("Thank you guys"));
string* p2 = p1.release();
cout << std::boolalpha << (p1 == nullptr); //true
}
那么在release()
,p1 == nullptr
之后,为什么在这种情况下不能释放分配的动态内存?我想念什么?
答案 0 :(得分:4)
为什么在这种情况下不能释放分配的动态内存? 我想念什么?
因为您已将其所有权转移到p2
。
现在您有了一个拥有的原始指针,可以通过delete
或将所有权转移到其他地方来清理原始指针。
您讨论的每个操作都有 distinct子句。使u
为空是 not u = nullptr
u = nullptr
u
指向的对象u
为空 u.release()
u
指向的对象的控制u
为空如果将“使u
为空”定义为等效于u = nullptr
,则将具有循环定义。相反,它意味着在操作之后,u == nullptr
是true
。
您可以自己实现unique_ptr
。这是一个(精简版)版本,展示了差异
template<typename T>
class unique_ptr
{
T* ptr;
public:
explicit unique_ptr(T* arg = nullptr) : ptr(arg) {}
~unique_ptr() { delete ptr; }
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
unique_ptr& operator=(std::nullptr_t) { delete ptr; ptr = nullptr; }
T* release() { T* temp = ptr; ptr = nullptr; return temp; }
friend bool operator==(const unique_ptr& lhs, const T* rhs) { return lhs.ptr == rhs; }
friend bool operator==(const T* lhs, const unique_ptr& rhs) { return lhs == rhs.ptr; }
}
该分配删除存在的所有内容,然后分配传递的参数。
release
复制成员,将其设置为nullptr
,然后返回副本。
答案 1 :(得分:1)
因为要释放指针的控制权,而不是删除它。例如,如果您想将unique_ptr
转换为shared_ptr
,该怎么办。您可能会这样:
shared_ptr<string> upgrade(p1.release());
您要从唯一指针的控制中释放指针,并设置一个可以控制它的共享指针。另一个示例可能是您是否希望将此指针传递给c
库。
在示例u = nullptr
中,您没有释放指针。没有人可以恢复u
的指向地址,因此必须将其删除。这是operator=
重载的一部分。
*实际上应如何将unique_ptr
转换为shared_ptr
是
std::shared_ptr<std::string> shared = std::move(unique);