智能指针

本文详细介绍了C++中的shared_ptr智能指针,包括其构造方法(包括无参、有参、浅拷贝和移动构造),重载操作符,独占性检查,使用计数,make_shared的用法以及析构时的行为。着重强调了线程安全性和计数器管理机制。
摘要由CSDN通过智能技术生成

欢迎访问我的博客首页


智能指针

1. shared_ptr


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

#include <mutex>

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 的实现
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值