智能指针

欢迎访问我的博客首页。


智能指针

  • 1. shared_ptr
  • 2. 参考

1. shared_ptr


  shared_ptr 的计数器是线程安全的。

#include 

template <typename T>
class Shared_ptr {
public:
    // 1.无参构造函数。
    Shared_ptr()
        : m_ptr(nullptr)
        , m_count(new size_t(0))
        , m_mutex(new std::mutex) {}
    // 2.有参构造函数(裸指针)。
    Shared_ptr(T *sptr)
        : m_ptr(sptr)
        , m_mutex(new std::mutex) {
        if (sptr) {
            m_count = new size_t(1);
        } else {
            m_count = new size_t(0);
        }
    }
    // 3.拷贝构造函数(浅拷贝)。
    Shared_ptr(const Shared_ptr &sptr)
        : m_ptr(sptr.m_ptr)
        , m_count(sptr.m_count)
        , m_mutex(sptr.m_mutex) {
        // 用 m_ptr = nullptr 的智能指针初始化另一智能指针,计数器不应改变。
        if (m_ptr != nullptr)
            // 改变 *m_count 没有改变 m_count 所以形参为 const。
            (*m_count)++;
    }
    // 4.移动构造函数。
    Shared_ptr(Shared_ptr &&sptr)
        : m_ptr(sptr.m_ptr)
        , m_count(sptr.m_count)
        , m_mutex(sptr.m_mutex) {
        sptr.set_ptr(nullptr);
        sptr.set_count(nullptr);
        sptr.set_mutex(nullptr);
    }
    // 5.移动赋值运算符重载。
    Shared_ptr &operator=(Shared_ptr &&sptr) {
        m_ptr = sptr.m_ptr;
        m_count = sptr.m_count;
        m_mutex = sptr.m_mutex;
        sptr.set_ptr(nullptr);
        sptr.set_count(nullptr);
        sptr.set_mutex(nullptr);
        return *this;
    }
    // 6.赋值运算符重载(浅拷贝)。
    Shared_ptr &operator=(const Shared_ptr &sptr) {
        if (this == &sptr)
            return *this;
        // 与所指对象切断连系。
        if (m_ptr != nullptr) {
            m_mutex->lock();
            (*m_count) -= 1;
            m_mutex->unlock();
            if (*m_count == 0) {
                delete m_ptr;
                m_ptr = nullptr;
                m_count = nullptr;
                m_mutex = nullptr;
            }
        }
        // 与新对象建立连系。
        m_ptr = sptr.m_ptr;
        m_count = sptr.m_count;
        m_mutex = sptr.m_mutex;
        // 用 m_ptr = nullptr 的智能指针初始化另一智能指针,计数器不应改变。
        if (m_ptr != nullptr) {
            m_mutex->lock();
            (*m_count) += 1;
            m_mutex->unlock();
        }
        return *this;
    }
    // 7.重载操作符:判断是否为0、NULL。
    bool operator==(const int b) { return m_ptr == 0; }
    bool operator!=(const int b) { return m_ptr != 0; }
    // 7.重载操作符:判断是否为nullptr。
    bool operator==(const nullptr_t &b) { return m_ptr == b; }
    bool operator!=(const nullptr_t &b) { return m_ptr != b; }
    // 7.重载操作符:判断两个智能指针是否指向同一个对象。
    bool operator==(const Shared_ptr &b) { return m_ptr == b.m_ptr; }
    bool operator!=(const Shared_ptr &b) { return m_ptr != b.m_ptr; }
    // 7.重载布尔值操作符:if(x)判断是否为空指针。
    operator bool() { return m_ptr == nullptr; }
    // 8.获取裸指针。
    T *get() { return m_ptr; }
    // 9.箭头运算符:获取裸指针所指对象的成员。
    T *operator->() { return m_ptr; }
    // 10.解引用运算符:获取裸指针所指对象。
    T &operator*() { return *m_ptr; }
    // 11.是否独占对象。
    bool unique() {
        // 移动构造函数和移动赋值函数会使所有成员指针置空。
        return !m_ptr || *m_count == 1;
    }
    // 12.获取共享数量。
    size_t use_count() {
        // 移动构造函数和移动赋值函数会使所有成员指针置空。
        return m_count ? *m_count : 0;
    }
    // 13.与另一个智能指针交换。
    void swap(Shared_ptr &sptr) { std::swap(*this, sptr); }
    // 14.析构函数。
    ~Shared_ptr() {
        // 移动构造函数和移动赋值函数会使所有成员指针置空。
        if (m_count != nullptr) {
            if (*m_count > 0) {
                m_mutex->lock();
                (*m_count)--;
                m_mutex->unlock();
            }
            if (*m_count == 0) {
                delete m_ptr;
                m_ptr = nullptr;
                m_count = nullptr;
                m_mutex = nullptr;
            }
        }
    }

private:
    void set_ptr(T *m_ptr) { this->m_ptr = m_ptr; }
    void set_count(size_t *m_count) { this->m_count = m_count; }
    void set_mutex(std::mutex *m_mutex) { this->m_mutex = m_mutex; }

private:
    T *m_ptr;
    size_t *m_count;
    std::mutex *m_mutex;
};

template <typename T, typename... Args>
// 返回值不能是引用类型。
Shared_ptr<T> Make_shared(Args &&...args) {
    Shared_ptr<T> s_ptr(new T(std::forward<Args>(args)...));
    return s_ptr;
}

2. 参考


  1. 智能指针的实现
  2. 智能指针的实现
  3. make_shared 的实现

你可能感兴趣的:(C++应用,c++)