Counter类

Counter对象的目地就是用来申请一个块内存来存引用计数和弱引用计数。shareCount是SharedPtr的引用计数,weakCount是弱引用计数。

  • 当shareCount为0时,删除T*对象。
  • 当weakCount为0同时shareCount为0时,删除Counter*对象。

Counter实现如下:

class Counter
{public:int shareCount = 0;int weakCount = 0;
};

SharedPtr类

主要的成员函数包括:

  • 默认构造函数
  • 参数为T*的explicit单参数构造函数
  • 参数为WeakPtr&的explicit单参数构造函数
  • 拷贝构造函数
  • 拷贝赋值函数
  • 析构函数
  • 隐式类型转换操作符 operator bool ()
  • operator -> ()
  • operator * ()
  • reset()
  • get()
  • use_count()

SharedPtr实现如下:

template<class T> class WeakPtr;
template<class T> class SharedPtr
{public:friend class WeakPtr<T>; //方便weak_ptr与share_ptr设置引用计数和赋值。SharedPtr(): m_pResource(nullptr), m_pCounter(nullptr){}explicit SharedPtr(T* pResource = nullptr) // 禁止隐式装换: m_pResource(pResource), m_pCounter(nullptr){if (m_pResource != nullptr){m_pCounter = new Counter;m_pCounter->shareCount = 1;}}SharedPtr(const WeakPtr<T>& other) // 供WeakPtr的lock()使用: m_pResource(other.m_pResource), m_pCounter(other.m_pCounter){if (m_pCounter != nullptr && 0 == m_pCounter->shareCount){m_pResource = nullptr; }}SharedPtr(const SharedPtr<T>& other): m_pResource(other->m_pResource), m_pCounter(other->m_pCounter){if (m_pCounter != nullptr) {++(m_pCounter->shareCount); // 增加引用计数}}SharedPtr<T>& operator = (const SharedPtr<T>& other){if (this == &other) return *this;release();m_pCounter = other.m_pCounter;m_pResource = other.m_pResource;if (m_pCounter != nullptr) {++(m_pCounter->shareCount); // 增加引用计数}return *this;}~SharedPtr(){release();}T& operator bool(){return m_pResource != nullptr;}T& operator * (){// 如果nullptr == m_pResource,抛出异常return *m_pResource;}T* operator -> (){return m_pResource;}void Reset(T* pOther = nullptr){release();m_pResourse = pOther;if (m_pResourse != nullptr){m_pCounter = new Counter();m_pCounter->shareCount = 1;}}T* get(){return m_pResource;}int use_count(){return (m_pCounter != nullptr) ? m_pCounter->shareCount : 0;}private:void release(){if (nullptr == m_pCounter) return;// T*肯定由SharedPtr释放,Counter*如果没有WeakPtr,也由SharedPtr释放--m_pCounter->shareCount;if (0 == m_pCounter->shareCount){delete m_pResource;m_pResource = nullptr;if (0 == m_pCounter->weakCount){delete m_pCounter;m_pCounter = NULL;}}}public:T* m_pResource = nullptr;Counter* m_pCounter = nullptr;
};

WeakPtr类

主要的成员函数包括:

  • 默认构造函数
  • 参数为SharedPtr&的explicit单参数构造函数
  • 拷贝构造函数
  • 拷贝赋值函数
  • 析构函数
  • lock()函数:取指向的SharePtr,如果未指向任何SharePtr,或者已被析构,返回指向nullptr的SharePtr
  • expired()函数:是否指向SharePtr,如果指向Share Ptr其是否已经析构
  • release()函数

WeakPtr实现如下:

template<class T> class WeakPtr
{public:friend class SharedPtr<T>;//方便weak_ptr与share_ptr设置引用计数和赋值。WeakPtr(): m_pResource(nullptr), m_pCounter(nullptr){}WeakPtr(SharedPtr<T>& other) : m_pResource(other.m_pResource), m_pCounter(other.m_pCounter){if (m_pCounter != nullptr){++(m_pCounter->weakCount);}}WeakPtr(WeakPtr<T>& other): m_pResource(other.m_pResource), m_pCounter(other.m_pCounter){if (m_pCounter != nullptr){++(m_pCounter->weakCount);}}WeakPtr<T>& operator = (WeakPtr<T>& other){if (this == &other) return *this;release();m_pCounter = other.m_pCounter;m_pResource = other.m_pResource;if (m_pCounter != nullptr){++(m_pCounter->weakCount);}return *this;}WeakPtr<T>& operator =(SharedPtr<T>& other){release();m_pCounter = other.m_pCounter;m_pResource = other.m_pCounter;if (m_pCounter != nullptr){++(m_pCounter->weakCount);}return *this;}~WeakPtr(){release();}SharedPtr<T> lock(){return SharedPtr<T>(*this);}bool expired(){if (m_pCounter != nullptr && m_pCounter->shareCount > 0)return false;return true;}private:void release(){if (nullptr == m_PCounter) return;--m_pCounter->weakCount;if (0 == m_pCounter->weakCount && 0 == m_pCounter->shareCount) // 必须都为0才能删除{delete m_pCounter;m_pCounter = NULL;}}private:T* m_pResource; // 可能会成为悬挂指针 此时m_pCounter->shareCount = 0Counter* m_pCounter;
};

C++ 智能指针shared_ptr、weak_ptr的简单实现相关推荐

  1. 深入学习c++--智能指针(二) weak_ptr(打破shared_ptr循环引用)

    1. 几种智能指针 1. auto_ptr: c++11中推荐不使用他(放弃) 2. shared_ptr: 拥有共享对象所有权语义的智能指针 3. unique_ptr: 拥有独有对象所有权语义的智 ...

  2. C++智能指针shared_ptr、unique_ptr以及weak_ptr

    目录 shared_ptr类 shared_ptr和unique_ptr都支持的操作 shared_ptr独有的操作 make_shared函数 shared_ptr自动销毁所管理的对象 由普通指针管 ...

  3. 智能指针(shared_ptr、unique_ptr、weak_ptr)的使用

    智能指针的使用 一.shared_ptr 1.创建一个shared_ptr 2.shared_ptr的常用成员函数 reset成员函数的使用 3.==注意事项== 二.unique_ptr 1.uni ...

  4. C++智能指针:weak_ptr实现详解

    文章目录 weak_ptr描述 声明 作用 原理实现 函数成员使用 总结 weak_ptr描述 声明 头文件:<memory> 模版类:template <class T> c ...

  5. Boost智能指针——shared_ptr

    boost::scoped_ptr虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而boost::shared_ptr可以解决这一局限.顾名思义,boost::shared_ptr是可以 ...

  6. 智能指针shared_ptr的几个例子

    #include <string> #include <iostream> #include <memory> //智能指针定义在头文件memory中,例如shar ...

  7. 智能指针shared_ptr的原理、用法和注意事项

    智能指针shared_ptr的原理.用法和注意事项 1 前言 2 shared_ptr原理 3 shared_ptr的基本用法 3.1 初始化 3.2 获取原始指针 4 智能指针和动态数组 4.1 c ...

  8. 智能指针shared_ptr的用法

    智能指针shared_ptr的用法 2016-12-03 15:39 by jiayayao, 360 阅读, 0 评论, 收藏, 编辑 为了解决C++内存泄漏的问题,C++11引入了智能指针(Sma ...

  9. get方法报空指针_智能指针shared_ptr踩坑笔记

    平时写代码一直避免使用指针,但在某些场景下指针的使用还是有必要的.最近在项目中简单使用了一下智能指针(shared_ptr),结果踩了不少坑,差点就爬不出来了.痛定思痛抱着<Cpp Primer ...

  10. 智能指针shared_ptr

    如果有可能就使用unique_ptr,然后很多时候对象是需要共享的,因此shared_ptr也就会用得很多.shared_ptr允许多个指向同一个对象,当指向对象的最后一个shared_ptr销毁时, ...

最新文章

  1. iOS开发- OpenGL ES屏幕截图
  2. 360浏览器、chrome开发扩展插件教程(2)为html添加行为
  3. 让Tee 7.x版本和FastReport 3.x版本共存
  4. 编写junit 测试_使用JUnit和Repeat注​​释编写有效的负载测试
  5. java不建议用全局变量吗_不要使用全局变量, ThreadLocal也不行
  6. 好家伙,这才是最强的目标检测落地模型!
  7. 微服务架构设计,对云原生的超越12因素了解吗,使用于所有语言!!!
  8. 东航期货模拟交易brockerid(期货公司的客户号)
  9. python xampp mysql_让XAMPP支持Python及Django
  10. 测试 —— 与开发双手互搏的艺术
  11. xshell和xftp免费版官方(家庭、学校版)下载
  12. COPRA RF 2005_
  13. 产品经理简历怎么写?看这一篇就够了
  14. 网络应用程序体系结构
  15. 前嗅ForeSpider数据采集教程:采集东方财富网链接列表
  16. iOS 真机模拟内存警告
  17. 手机照片丢失怎么才能恢复
  18. [CSP-S 2022] 策略游戏
  19. 用python识别微信消息界面聊天输入框位置
  20. Java 遍历HashMap并修改(remove)

热门文章

  1. Python和C++的混合编程(使用Boost编写Python的扩展包)
  2. 转载:Futurice-Android 开发最佳实践
  3. 【探索PowerShell 】【七】变量
  4. WCF笔记--泛型与集合数据类型
  5. 活动选择问题(贪心)
  6. 安卓开发中Theme.AppCompat.Light的解决方法
  7. eclipse进度条从后台还原到前台
  8. Activity详解 Intent显式跳转和隐式跳转, 及多个Activity之间传值 总结
  9. 设计模式学习每天一个——Bridge模式
  10. 为什么修改配置文件要重启server