C++智能指针(2):unique_ptr 分析 在使用 AutoPointer 的时候会发生所有权转移和内存泄漏的问题,所以我们可以对 AutoPointer 类稍加修改,修复这两个问题。
所有权转移 为了规避可能发生所有权转移的情况,我们可以直接禁止它使用拷贝构造函数和赋值操作符。
UniquePointer(UniquePointer<T> &other) = delete; UniquePointer<T> &operator=(const UniquePointer<T> &other) = delete; 但很多时候我们都需要使用到传递指针的操作,如果只是使用 deleted 函数禁止拷贝构造函数和赋值操作符,那么这个智能指针存在的意义就不大了,我们可以通过 move 语义来实现移动构造函数和移动赋值操作符,从而在使用 UniquePointer 的时候可以在特定情况下进行所有权转移。
UniquePointer(UniquePointer<T> &&other) noexcept; UniquePointer &operator=(UniquePointer &&other) noexcept; 内存泄漏 为了防止发生内存泄漏,我们可以在UniquePointer的私有成员中增加一个删除器,并根据当前指针对象的类型指定删除器,从而防止发生内存泄漏。
class Deleter { template<typename T> void operator()(T *p) { if (p) delete p; } }; template<typename T, typename D> class UniquePointer { ... private: T *pointer; Deleter deleter; }; 实现 根据unique_ptr的源码,能够大致实现UniquePointer类
template<typename T, typename D> class UniquePointer { public: explicit UniquePointer(T *t, const D &d); ~UniquePointer(); T &operator*(); T *operator->(); T *release(); void reset(T *p); UniquePointer(UniquePointer &&other) noexcept; UniquePointer &operator=(UniquePointer &&other) noexcept; UniquePointer(const UniquePointer &other) = delete; UniquePointer &operator=(const UniquePointer &other) = delete; private: T *pointer; D deleter; }; template<typename T, typename D> UniquePointer<T, D>::UniquePointer(T *t, const D &d) { std::cout << "UniquePointer " << this << " constructor called....