• 智能指针


    欢迎访问我的博客首页


    智能指针

    4.共享指针的实现

    template <typename T>
    class Shared_ptr {
    public:
    	// 1.无参构造函数。
    	Shared_ptr() :m_ptr(nullptr), m_count(new size_t(0)) {}
    	// 2.有参构造函数(裸指针)。
    	Shared_ptr(T* ptr) :m_ptr(ptr), m_count(new size_t(1)){} 
    	// 3.拷贝构造函数(浅拷贝)。
    	Shared_ptr(const Shared_ptr& ptr) :m_ptr(ptr.m_ptr), m_count(ptr.m_count) {
    		if (m_ptr != nullptr)  // 用m_ptr=nullptr的智能指针初始化另一智能指针,计数器不应改变。
    			(*m_count)++; // 改变*m_count没有改变m_count所以形参为const。
    	}
    	// 4.移动构造函数。
    	Shared_ptr(Shared_ptr&& ptr) :m_ptr(ptr.m_ptr), m_count(ptr.m_count) {
    		ptr.set_ptr(nullptr);
    		ptr.set_count(nullptr);
    	}
    	// 5.移动赋值运算符重载。
    	Shared_ptr& operator=(Shared_ptr&& ptr) {
    		m_ptr = ptr.m_ptr;
    		m_count = ptr.m_count;
    		ptr.set_ptr(nullptr);
    		ptr.set_count(nullptr);
    		return *this;
    	}
    	// 6.赋值运算符重载(浅拷贝)。
    	Shared_ptr& operator=(const Shared_ptr& ptr) {
    		if (this == &ptr)
    			return *this;
    		// 与所指对象切断连系。
    		if (m_ptr != nullptr) {
    		    (*m_count) -= 1;
    		    if (*m_count == 0) {
    		        delete m_ptr;
    		        m_ptr = nullptr;
    		        m_count = nullptr;
    			}
    		}
    		// 与新对象建立连系。
    		m_ptr = ptr.m_ptr;
    		m_count = ptr.m_count;
    		if (m_ptr!= nullptr) // 用m_ptr=nullptr的智能指针初始化另一智能指针,计数器不应改变。
    		(*m_count) += 1;
    		return *this;
    	}
    	// 7.重载操作符:判断是否为0、NULL。
    	bool operator==(const int b) { return (m_ptr == 0) ^ b; }
    	bool operator!=(const int b) { return !((m_ptr == 0) ^ b); }
    	// 7.重载操作符:判断是否为nullptr。
    	bool operator==(const nullptr_t& b) { return m_ptr == b; }
    	bool operator!=(const nullptr_t& b) { return m_ptr != b; }
    	// 7.重载布尔值操作符:if(x)判断是否为空指针。
    	operator bool() { return m_ptr == nullptr; }
    	T* get() { return m_ptr; } // 8.获取裸指针。
    	T* operator->() { return m_ptr; } // 9.箭头运算符:获取裸指针所指对象的成员。
    	T& operator*() { return *m_ptr; } // 10.解引用运算符:获取裸指针所指对象。
    	bool unique() { return *m_count == 1; } // 11.是否独占对象。
    	size_t use_count() { return m_count ? *m_count: 0; } // 12.获取共享数量。
    	void swap(Shared_ptr& ptr) { std::swap(*this, ptr); } // 13.交换两个智能指针。
    	// 14.析构函数。
    	~Shared_ptr() {
    		if (m_count != nullptr) { // 移动构造函数和移动赋值会把两个成员指针置空。
    			if (*m_count > 0)
    		        (*m_count)--;
    			if (*m_count == 0) {
    		        delete m_ptr;
    		        m_ptr = nullptr;
    		        m_count = 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; }
    
    private:
    	T* m_ptr;
    	size_t* m_count;
    };
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    4. 参考


    1. 智能指针的实现
    2. 智能指针的实现
    3. make_shared 的实现
  • 相关阅读:
    R语言layout () 函数
    vue基础知识十:Vue中组件和插件有什么区别?
    tars 的基本使用——使用 tars 发布服务
    微机原理实验:字符转换为ASCII码
    自己动手从零写桌面操作系统GrapeOS系列教程——1.2 GrapeOS真机演示
    【ESD专题】案例 :结构设计导致的ESD问题
    1、Flink DataStreamAPI 概述(上)
    Python3中的“加和”函数
    Vue项目中配置eslint
    AlmaLinux download
  • 原文地址:https://blog.csdn.net/qq_26697045/article/details/134432061