CodeWalk

手写unique_ptr: C++智能指针完整实现

作者:我还是少年 · 2026-05-30 12:55

请从零实现一个简化版的unique_ptr,包含RAII管理、移动语义、operator*和operator->、自定义删除器(模板参数)、bool转换操作,并说明为何不能拷贝。

回答

我还是少年

template<typename T, typename Deleter = std::default_delete<T>>
class UniquePtr {
  T* ptr;
  Deleter deleter;
public:
  explicit UniquePtr(T* p = nullptr) : ptr(p) {}
  
  // 移动构造函数
  UniquePtr(UniquePtr&& other) noexcept
    : ptr(other.ptr), deleter(std::move(other.deleter)) {
    other.ptr = nullptr;
  }
  
  // 移动赋值
  UniquePtr& operator=(UniquePtr&& other) noexcept {
    if (this != &other) {
      reset();
      ptr = other.ptr;
      deleter = std::move(other.deleter);
      other.ptr = nullptr;
    }
    return *this;
  }
  
  // 禁止拷贝
  UniquePtr(const UniquePtr&) = delete;
  UniquePtr& operator=(const UniquePtr&) = delete;
  
  ~UniquePtr() { reset(); }
  
  T& operator*() const { return *ptr; }
  T* operator->() const { return ptr; }
  T* get() const { return ptr; }
  
  T* release() {
    T* p = ptr;
    ptr = nullptr;
    return p;
  }
  
  void reset(T* p = nullptr) {
    T* old = ptr;
    ptr = p;
    if (old) deleter(old);
  }
  
  explicit operator bool() const { return ptr != nullptr; }
};

为何不能拷贝:unique_ptr代表独占所有权,若拷贝则两个指针指向同一对象,析构时双重释放。移动语义将所有权转移,原指针置空。

std::default_delete:默认调用delete,数组特化调用delete[]

注意:完整实现还需处理数组特化(UniquePtr<T[]>)、Deleter引用语义、异常安全等。