c++简略实现共享智能指针Shared_Ptr<T>

重点:

1.引用计数在堆上(原本应为原子变量)

2.引用计数增加减少需要加锁保证线程安全。

3.内部实现Release函数用于释放资源

4.未实现,增加自定义删除器可以将Release修改为模板函数,传入可调用参数。对于shared_ptr,删除器应当作为构造函数参数传入。故而成员函数需要有std::function对象。

#ifndef SHARED_PTR_SHARED_PTR_H
#define SHARED_PTR_SHARED_PTR_H
#include <mutex>

template<typename T>
class Shared_ptr{
public:
    Shared_ptr(T * row) :
    _row_ptr(row),
    _ref_count(new int(1)),
    _ref_mux(new std::mutex)
    {}

    ~Shared_ptr(){ release(); }
    //拷贝构造
    Shared_ptr(const Shared_ptr<T> &sp) :
    _row_ptr(sp._row_ptr),
    _ref_count(sp._ref_count),
    _ref_mux(sp._ref_mux)
    { add_ref(); }
    //拷贝赋值
    Shared_ptr<T>& operator=(const Shared_ptr<T> &sp){
        if (this->_row_ptr != sp._row_ptr){
            release();  //释放管理的旧资源
            _row_ptr = sp._row_ptr;
            _ref_count = sp._ref_count;
            _ref_mux = sp._ref_mux;
            add_ref();
        }
        return *this;
    }

public:
    int& use_count(){ return *_ref_count; }

    T& operator*(){ return *_row_ptr; }

    T* operator->(){ return _row_ptr; }

    T* get(){ return _row_ptr; };

    void reset(T *sp){
        if (this->_row_ptr != sp){
            release();  //释放旧资源,减少引动计数
            _row_ptr = sp;
            _ref_count = new int(1);
            _ref_mux = new std::mutex;
        } else
            add_ref();
    }

private:
    T *_row_ptr;
    int *_ref_count;
    std::mutex *_ref_mux;
    //减少引用计数或释放内存
    void release(){
        std::unique_lock<std::mutex> lock(*_ref_mux);
        if (--(*_ref_count) == 0){
            delete _row_ptr;
            delete _ref_count;
            _row_ptr = nullptr; //避免悬空指针
            _ref_count = nullptr;
        }
    }
    //保证线程安全的前提下加锁增加引用计数
    void add_ref(){
        std::unique_lock<std::mutex> lock(*_ref_mux);
        ++(*_ref_count);
    }
};

#endif //SHARED_PTR_SHARED_PTR_H

测试程序:

#include <iostream>
#include <string>
#include "Shared_ptr.h"

int main() {
    Shared_ptr<std::string> ptr1(new std::string("hello"));
    Shared_ptr<std::string> ptr2(ptr1);
    std::cout << "ptr2 use_count = " << ptr2.use_count() << "ptr1 use_count = " << ptr1.use_count() << std::endl;

    Shared_ptr<std::string> ptr3 = ptr2;
    std::cout << "ptr3 use_count = " << ptr3.use_count() << std::endl;

    std::cout << *ptr2 << std::endl;
    auto str = new std::string("ni hao");
    ptr2.reset(str);
    std::cout << *ptr2 <<" ptr2 usecount = " << ptr2.use_count() << std::endl;
    std::cout << ptr1.use_count() << std::endl;

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/682992.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

tomcat服务器之maxHttpHeaderSize

背景&#xff1a;在OA流程表单中&#xff0c;填写了200条数据&#xff0c;一提交&#xff0c;秒报400错误&#xff0c;且请求没有打到后端中&#xff08;无报错日志&#xff09;&#xff0c;一开始以为是谷歌浏览器的问题&#xff0c;可百度上关于这个错误的解决方案都是清除缓…

docker实战流程:

Docker-compose是docker官方的开源项目&#xff0c;负责实现对docker容器的集群的快速编排&#xff08;通过yaml文件docker-compose.yml管理写好容器之间的调用关系只需一个命令就能实现容器的通识开启或关闭&#xff09;。 类比spring容器&#xff0c;spring管理的是bean而do…

vue3+uniapp

1.页面滚动 2.图片懒加载 3.安全区域 4.返回顶部&#xff0c;刷新页面 5.grid布局 place-self: center; 6.模糊效果 7.缩放 8.微信小程序联系客服 9.拨打电话 10.穿透 11.盒子宽度 12.一般文字以及盒子阴影 13.选中文字 14.顶部安全距离 15.onLoad周期函数在setup语法糖执行后…

PVE安装虚拟主机

本文记录PVE安装其他虚拟主机的步骤&#xff0c;以安装win-server为例。裸机安装PVE则不是本文主题。 准备文件 获取Windows系统镜像 win server镜像可以从官网获取普通Windows镜像可从MSDN获取此外&#xff0c;安装Windows系统还需要从PVE下载特殊驱动 获取Windows必要驱动 …

数据库(25)——多表关系介绍

在项目开发中&#xff0c;进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;各个表之间的结构基本上分为三种&#xff1a;一对多&#xff0c;多对多&#xff0c;一对一。 一对多 例如&#xff0c;一个学校可以有…

PromptPerfect:AI Prompt生成与优化专家

PromptPerfect&#xff1a;AI Prompt生成与优化专家 PromptPerfect是一款专业的AI Prompt生成与优化工具&#xff0c;旨在帮助用户解锁和最大化GPT-4、ChatGPT、Midjourney等先进AI模型的潜力。它通过智能生成和精细优化Prompt&#xff0c;帮助用户获得更精确、更相关、更高效…

Aws EC2,kubeadm方式安装kubernetes(k8s)

版本 docker版本&#xff1a;20.10.25 k8s版本&#xff08;kubeadm&#xff0c;kubelet和kubectl&#xff09;&#xff1a;1.20.10-0 初始化 # 禁用 SELinux sudo setenforce 0 sudo sed -i s/^SELINUXenforcing$/SELINUXpermissive/ /etc/selinux/config# 关闭防火墙 sudo …

题号:BC19 题目:反向输出一个四位数

题号&#xff1a;BC19 题目&#xff1a;反向输出一个四位数 废话不多说&#xff0c;上题目&#xff1a; 解题思路&#xff1a; 我们发现可以用%和/两个操作符就可以解决。 代码如下: int main() {int a 0;scanf("%d ",& a);while (a){printf("%d "…

【实物+仿真设计】基于单片机的物流皮带传输监控系统设计

《基于单片机的物流皮带传输监控系统设计 实物仿真》 整体功能&#xff1a; 本设计采用以单片机为核心控制器&#xff0c;以及传感器检测部分作为输入部分&#xff0c;以报警、显示、洒水、排烟、电机停止模块作为输出部分&#xff0c;构成整个物流皮带传输监控系统。 本设计…

Kolmogorov–Arnold Networks (KAN) 即将改变 AI 世界

目录 一、说明 二、KAN介绍 2.1 什么是 Kolmogorov-Arnold Networks &#xff08;KAN&#xff09;&#xff1a; 2.2 KAN 的秘诀&#xff0c;Splines&#xff01; 2.3 了解KAN工作的最简单方法 三、KAN的主要优点 四、KAN 的 Python 实现 &#xff08;PyKAN&#xff09; 4.1 …

神经网络 | 深度学习背后的数学

神经网分析 机器学习处理的是数据&#xff0c;通过学习输入的数据&#xff0c;从而建立模型&#xff0c;以便预测新的数据的输出 按照类型可以进行如下分类 监督分类 非监督分类 强化学习 神经元 生物学中&#xff0c;人的大脑是由多个神经元互相连接形成网络而构成的。也…

访问vue乱码解决

前情提要&#xff1a; 前端 vue工程npm run build生成的dist静态文件 后端 springboot 后端mvn install 生成war包&#xff0c;前端dist放进war包 报错&#xff1a; 页面访问白屏 报错如图 可以看到chunk-vendors.xxxx.js出现了中文乱码&#xff0c;这个js文件是vue build生成的…

2024版本---LabVIEW 软件安装及使用教程

目录 第1章 LabVIEW 软件安装及使用教程 1. 简介 2. 安装教程 2.1 下载 LabVIEW 2024 版本 2.2 安装 LabVIEW 3. 激活 LabVIEW 4. LabVIEW 基本使用教程 4.1 用户界面介绍 4.2 创建一个简单的 VI&#xff08;虚拟仪器&#xff09; 4.3 数据采集示例 5. 进阶功能介绍…

秋招突击——算法打卡——6/5——提高{(状态机模型)股票买卖、(单调队列优化DP)最大子序列和}——新做:{考试的最大困扰度}

文章目录 提高(状态机模型)股票买卖IV思路分析实现代码参考代码 新作考试的最大困扰度个人实现参考思路 总结 提高 (状态机模型)股票买卖IV 上一次的思路总结&#xff0c;上次写的时候忘记总结了&#xff0c;现在重新画一下图 思路分析 这道题是一个经典的状态机模型&#…

【数据挖掘】学习笔记

文章目录 第一章 引论1.1 为什么进行数据挖掘1.2 什么是数据挖掘&#xff1f;1.3 可以挖掘什么类型的数据1.4 可以挖掘什么类型的模式1.4.1 类/概念描述&#xff1a;特征化和区分1.4.2 挖掘频繁模式、关联规则和相关性1.4.3 用于预测分析的分类和回归1.4.4 聚类分析1.4.5 离群点…

【C语言之排序】-------六大排序

作者主页&#xff1a;作者主页 数据结构专栏&#xff1a;数据结构 创作时间 &#xff1a;2024年5月18日 前言&#xff1a; 今天我们就给大家带来几种排序的讲解&#xff0c;包括冒泡排序&#xff0c;插入排序&#xff0c;希尔排序&#xff0c;选择排序&#xff0c;堆排序&…

计算机网络ppt和课后题总结(下)

常用端口总结 计算机网络中&#xff0c;端口是TCP/IP协议的一部分&#xff0c;用于标识运行在同一台计算机上的不同服务。端口号是一个16位的数字&#xff0c;范围从0到65535。通常&#xff0c;0到1023的端口被称为“熟知端口”或“系统端口”&#xff0c;它们被保留给一些标准…

【Python数据类型的奥秘】:构建程序基石,驾驭信息之海

文章目录 &#x1f680;Python数据类型&#x1f308;1. 基本概念⭐2. 转化&#x1f44a;3. 数值运算&#x1f4a5;4. 数值运算扩展(math库常用函数) &#x1f680;Python数据类型 &#x1f308;1. 基本概念 整数&#xff08;int&#xff09;&#xff1a;整数是没有小数部分的数…

保研面试408复习 8——计算机网络(浏览器http)、离散数学(平面图)、操作系统、数据结构

文章目录 一、计算机网络1、从在浏览器输入网址到页面显示的过程1. 输入网址2. DNS 解析3. 建立TCP连接4. 发送HTTP请求5. 服务器处理请求并响应6. 浏览器处理响应7. 页面渲染 二、离散数学一、平面图1、平面图性质2、Kuratowski定理 三、操作系统四、数据结构 一、计算机网络 …

Unity3d使用3D WebView for Windows and macOS打开全景网页(720云)操作问题记录

问题描述 使用Unity3d内嵌网页的形式打开720云中的全景图这个功能&#xff0c;使用的是3D WebView for Windows and macOS插件&#xff0c;720云的全景图在浏览器上的操作是滑动鼠标滚轮推远/拉近全景图&#xff0c;鼠标左键拖拽网页可以旋转全景图内容。网页的打开过程是正常…