C++ delete ptr 和 ptr = nullptr 的区别
delete ptrdelete ptr 是释放 ptr 所指向的对象资源,而 ptr 依然存在,且依然指向那片内存地址。 ptr = nullptrptr = nullptr 是将 ptr 指向空指针,和其所指向的对象没关系。 试着实现一个 unique_ptrtemplate <typename T> class UniquePtr { private: T *_ptr; public: // 默认构造 UniquePtr() : _ptr(nullptr) { } explicit UniquePtr(T *ptr) : _ptr(ptr) { } ~UniquePtr() { delete _ptr; // 无需置 nullptr,因为析构函数会被调用,_ptr 会被销毁 // 置空无意义 } // 拷贝构造 删除 UniquePtr(const UniquePtr &) = delete; UniquePtr &operator=(const UniquePtr &) = delete; // 移动构造 UniquePtr(UniquePtr &&p) noexcept : _ptr(p._ptr) { // 至于这里为什么不需要 delete _ptr // 是因为这是移动构造函数,是个构造函数!_ptr 本来就没有资源 p._ptr = nullptr; } UniquePtr &operator=(UniquePtr &&p) noexcept { if (p != *this) { delete _ptr; // 第一步,释放当前资源 _ptr = p._ptr; // 第二步,将当前指针指向新的资源 p._ptr = nullptr; // 第三步,将原来的指针置空 } return *this; } T *get() const { // 返回指针 return _ptr; } T *operator->() const { // 返回指针 return _ptr; } T &operator*() const { // 解引用 return *_ptr; } T *release() { // 这里不能 delete _ptr // 因为 release 只是解除 UniquePtr 对资源的所有权,但资源还是存在的 T *tmp = _ptr; _ptr = nullptr; return tmp; } void reset(T *newptr = nullptr) { if (_ptr != newptr) { delete _ptr; // 释放当前资源 _ptr = newptr; // 指向新资源 // 这里不需要置空 newptr // 是否置空 new ptr 由用户决定 } } }; UniquePtr &operator=(UniquePtr &&p) 移动赋值运算符的原理如下图: ...