基于引用计数的shared_ptr的简单实现

2023-11-14

//简易版的智能指针 多线程中智能指针的读取对象是不安全的
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
template<typename T>//智能指针就是包装了指向T类型的指针
class Ptr{
public:
    Ptr(T*p= nullptr):mptr(p){
//        mcount=new size_t(1);//无论是什么内容都把这个初始值设为1.保证能对mcount进行销毁
        if(mptr!= nullptr) {
            mcount=new size_t(1);//只有内容不为空时才开始计数,这样确实是比较合理的
        }
        cout<<"first construct"<<endl;
        if(mptr!= nullptr) cout<<"info"<<*mptr<<endl;
    }
    ~Ptr(){
        (*mcount)--;
        if((*mcount)==0){
            delete mcount;
            delete mptr;
            cout<<"destroy all"<<endl;
        }
    }
    Ptr(const Ptr& other){//拷贝赋值是引用类型
        mptr=other.mptr;
        mcount=other.mcount;
        (*mcount)++;
        cout<<"copy"<<*mcount<<endl;
    }

    Ptr& operator=(const Ptr&other){//赋值函数, 为什么返回类型是引用 要判断是不是在同一块区间 回答:返回值是引用才可以连续进行赋值;形参类型是引用,避免重复调用拷贝构造函数
        if(this!=&other)//如果是同一个对象不进行实例操作。赋值的时候需要去进行判断赋值的对象和待赋值的对象是否已经相同,相同的话会错误的删除原来的内存空间,然后又进行了错误的赋值。
        {
            Ptr tmp(other);//避免地址判断,直接拷贝构造一个函数

            swap(tmp.mptr,mptr);
            swap(tmp.mcount,mcount);
            cout<<"addr not same"<<endl;

        }//保证了异常安全性,如果内存不够分配抛出异常不会修改原来的实例,保证了原来的数据安全性 成功分配内存后,自动销毁被赋值前对象的内存指向内容
        cout<<"assign"<<endl;
        return *this;  //返回Ptr的对象指针
    }


    T* operator->(){
        return  mptr;
    }
    //测试指针是否正确
    void test(){
        cout<<"test!"<<endl;
    }
    T& operator*(){
        return *mptr;
    }

private:
    T* mptr;
    size_t* mcount;
};
int main() {
    //int数据类型 测试类Ptr是否应用正确
//    Ptr<int> ptr(new int(2));//注意这里智能指针的构造方法
//    Ptr<int> ptr2(ptr);
//    cout<<"====="<<endl;
//    cout<<*ptr2<<endl;//对星号进行重载成功了
//    cout<<"====="<<endl;
//
//    cout<<"====="<<endl;
//    Ptr<int> ptr3(ptr);//在ptr3没有传递内容的指针构造的时候,默认是nullptr,所以只有构造函数,但是没有销毁函数,但是也不对,计数的new是在类里面的,所以要进行销毁。所以采取的策略就是mptr不为空才初始化计数为1,不然就是零。
//    ptr3=ptr;
//========//
//string 使用模板类定义自己的函数
//使用的时候可以看出来,智能指针仅仅是将指针进行了封装,智能指针定义的变量(比较小)是存在栈空间上,但是类里面有指针指向堆内存的内容(比较大),当超出作用域的时候就会自动调用析构函数,释放堆内存上面的空间
      Ptr<string> myptr(new string(10,'a'));//注意这里是采用构造函数的形式
      cout<<*myptr<<endl;
      Ptr<string> myptr2(new string(2,'b'));
      cout<<*myptr2<<endl;


      /*
       *标准库中使用智能指针shared_ptr和weak_ptr
       *
       * */
    shared_ptr<string> p= make_shared<string>(10,'a');
    weak_ptr<string> pw(p);
    cout<<pw.use_count()<<endl ;//弱引用可以观察次数,但不能直接访问内容,也就是*pw是非法的。
    shared_ptr<string> p2=pw.lock();//通过lock函数将弱引用转化成shared_ptr再进行使用
    cout<<*p2<<endl;
    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于引用计数的shared_ptr的简单实现 的相关文章

  • EntityHydrate 任务失败

    我最近安装了 Visual Studio 11 Beta 和 Visual Studio 2010 之后 我无法在 Visual Studio 2010 中构建依赖于 PostSharp 的项目 因此我卸载了 Visual Studio 1
  • 在 C 语言中,为什么数组的地址等于它的值?

    在下面的代码中 指针值和指针地址与预期不同 但数组值和地址则不然 怎么会这样 Output my array 0022FF00 my array 0022FF00 pointer to array 0022FF00 pointer to a
  • Boost ASIO 串行写入十六进制值

    我正在使用 ubuntu 通过串行端口与设备进行通信 所有消息都必须是十六进制值 我已经在 Windows 环境中使用白蚁测试了通信设置 并得到了我期望的响应 但在使用 Boost asio 时我无法得到任何响应 以下是我设置串口的方法 b
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • 用于在标头更改时重新编译的简单 C 项目的示例 makefile

    有谁有完整的 makefile 可以执行以下操作 如果 HEADER 文件发生更改 则重建项目 cpp 文件在 makefile 中列出 头文件未在 makefile 中列出 头文件允许与 cpp 文件具有不同的名称 部分cpp文件没有头文
  • 测量进程消耗的 CPU 时钟

    我用 C 语言编写了一个程序 它是作为研究结果创建的程序 我想计算程序消耗的确切 CPU 周期 精确的循环次数 知道我怎样才能找到它吗 The valgrind tool cachegrind valgrind tool cachegrin
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • C# 获取数据表中所有重复行的计数

    我通过运行存储过程来填充数据集 并且从数据集中填充数据表 DataSet RawDataSet DataAccessHelper RunProcedure storedprocedureName this will just return
  • wordexp 失败时我们需要调用 wordfree 吗?

    wordexp 失败时我们需要调用 wordfree 吗 在某些情况下 调用 wordfree 似乎会出现段错误 例如 当 wordfree 返回字符串为 foo bar 的错误代码时 这在手册页中并不清楚 我已经看到在某些错误情况下使用了
  • 如何在 Javascript 中连接 C# ActiveX 事件处理程序

    我尝试使用几个代码片段将 ActiveX 对象与 Javascript 事件处理程序挂钩 我无法确定为什么事件处理程序没有被调用 带有项目的 Github 存储库 https github com JesseKPhillips Csharp
  • 如何防止 Blazor NavLink 组件的默认导航

    从 Blazor 3 1 Preview 2 开始 应该可以防止默认导航行为 https devblogs microsoft com aspnet asp net core updates in net core 3 1 preview
  • 对于 C# Express 用户来说,有哪些好的工具可以识别可能重复的代码? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 也可以看看 有什么工具可以检查重复的 VB NET 代码吗 https stackoverflow c
  • ASP.NET Core 中间件与过滤器

    在阅读了 ASP NET Core 中间件之后 我对何时应该使用过滤器以及何时应该使用中间件感到困惑 因为它们似乎实现了相同的目标 什么时候应该使用中间件而不是过滤器 9频道有一个关于此的视频 ASP NET 怪物 91 中间件与过滤器 h
  • 读取依赖步行者输出

    I am having some problems using one of the Dlls in my application and I ran dependency walker on it i am not sure how to
  • .NET 和 Mono 之间的开发差异

    我正在研究 Mono 和 NET C 将来当项目开发时我们需要在 Linux 服务器上运行代码 此时我一直在研究 ASP NET MVC 和 Mono 我运行 Ubuntu 发行版 想要开发 Web 应用程序 其他一些开发人员使用 Wind
  • 构建 C# MVC 5 站点时项目之间的处理器架构不匹配

    我收到的错误如下 2017 年 4 月 20 日构建 13 23 38 C Windows Microsoft NET Framework v4 0 30319 Microsoft Common targets 1605 5 警告 MSB3
  • 如何编写一个接受 int 或 float 的 C 函数?

    我想用 C 语言创建一个扩展 Python 的函数 该函数可以接受 float 或 int 类型的输入 所以基本上 我想要f 5 and f 5 5 成为可接受的输入 我认为我不能使用if PyArg ParseTuple args i v
  • Streamwriter 覆盖 txt 文件中的文本

    有没有什么方法可以重新打开流写入器而不创建新的写入对象 因为此时 当调用 WriteOdd 时 streamwriter 正在覆盖在它之前调用的 WriteEven public void WriteEven StreamWriter wr
  • 从后面的代码添加外部 css 文件

    我有一个 CSS 文件 例如 SomeStyle css 我是否可以将此样式表文档从其代码隐藏应用到 aspx 页面 您可以将文字控件添加到标头控件中 Page Header Controls Add new System Web UI L
  • 如何在 C# 中获取 CMD/控制台编码

    我需要指定正确的代码页来使用 zip 库打包文件 正如我所见 我需要指定控制台编码 在我的例子中为 866 C Users User gt mode Status for device CON Lines 300 Columns 130 K

随机推荐

  • 推荐一个将MD格式的文档轻松转换到微信公众号的工具

    因为微信公众号自带的编辑器不是特别友好 这也是一个痛点 之前也有使用过google插件 但不是特别灵活 现在推荐的这款工具可以很好的支持将MD格式的文档直接进行渲染 还是非常好用的 话不多说 先给出工具地址 https md openwri
  • 花生壳 Linux arm

    安装和使用Linux花生壳服务 一 安装说明 以CentOS 5为例 1 安装必要的开发包 root localhost yum install gcc gcc c autoconf automake 2 下载phddns 2 0 2 16
  • MongoDB图形化工具下载和使用

    文章目录 MongoDB图形化工具 1 下载地址 2 打开MongoDB服务 3 Compass界面 3 1 连接Mongo 3 2 创建数据库 3 3 创建集合 3 4 删除集合 3 5 增 3 6 改 3 7 删 3 8 查 3 9 导
  • TRPO算法详解

    答主最近学到TRPO 这算法确实很难理解 现在记录答主现在的一点想法 留存记录 先放参考文献 方便大家学习 Reference 1 Sutton R S Barto A G Reinforcement learning An introdu
  • 数组指针数组的定义及使用(about array of pointer of array)

    数组指针数组 array pointer array 该怎么定义和使用呢 如下 定义 define MsgCnt 3 define MsgLen 8 typedef char MsgArray MsgCnt MsgLen typedef c
  • J2EE之XML建模

    目录 一 什么叫XML建模 二 XML建模 1 根据XML配置文件元素节点创建元素节点实体类 2 利用dom4j xpath技术实现XML建模 一 什么叫XML建模 将XML配置文件中的元素 属性 文本信息转换成对象的过程叫做XML建模 二
  • 实验四,静态成员与友元

    一 实验目的和要求 了解成员函数的特性 掌握静态成员 友元等概念 二 实验内容 1 调试下列程序 写出输出结果 并分析输出结果 sy4 1 cpp include
  • python 大乐透号码生成器

    选号规则 前区1 35的范围随机产生不重复的5个号码 后区在1 12范围内随机生成2个不重复的2个号码 如下 from random import sample def number front sample str i for i in
  • 一、PWM 输出控制电机

    PWM 输出控制电机 电机系列 一 PWM 输出控制电机 1 相关 IO 介绍 2 编写 PWM 输出库函数 PWM h PWM c 3 控制函数 control h control c 4 main函数 电机系列 一 PWM 输出控制电机
  • 关闭jvm的方式

    1 System exit status 不管status为何值都会退出程序 System exit 0 是正常退出程序 而System exit 1 或者说非0表示非正常退出程序 2 System exit 0 和dispose Syst
  • MySQL踩坑笔记(1)

    mysql gt set password for 用户名 localhost password 新密码 这个是错的 mysql gt alter user 用户名 登录主机 identified by 密码 自定义 这个是对的 mysql
  • Linux全网超详细RHLinux安装PHP8.2.9 (2023年8月最新版)

    目录 进入PHP官方网站 1 下载安装包 2 解压安装包文件 3 安装php文件 安装提示sqlite3 4 安装过程中出现错误修复 5 查看一下php版本 6 启动php服务 进入PHP官方网站 PHP网址 https www php n
  • keras卷积神经网络入门-笑脸检测

    keras卷积神经网络入门 笑脸检测 Keras简介 1 库函数导入 2 查看数据集 3 构建模型 4 训练模型 5 预测自己的图片 Keras简介 Keras以其强大的封装结构 让我们不必过多的考虑神经网络间的计算 极大简化了tensor
  • Java面试题——为 什 么 说 Synchronized 是 一 个 悲 观 锁 ?乐 观 锁 的 实 现 原 理又 是 什 么 ? 什 么 是 CAS, 它 有 什 么 特 性 ?

    a Synchronized 显 然 是 一 个 悲 观 锁 因 为 它 的 并 发 策 略 是 悲 观 的 不 管 是 否 会 产 生 竞 争 任 何 的 数 据操作 都 必 须 要 加 锁 用 户 态 核 心 态 转换 维 护 锁 计
  • 【延期公告】2022年第四届大数据、物联网与计算国际会议(ICBICC 2022)

    2022年第四届大数据 物联网与计算国际会议 ICBICC 2022 重要信息 会议网址 www icbicc org 会议时间 2022年12月2 4日 召开地点 四川成都 截稿时间 2022年11月1日 录用通知 投稿后2周内 收录检索
  • MySQL单表多字段去重

    MySQL单表多字段去重 1 编写查重语句 SELECT a 字段1 a 字段2 FROM 表名 as a GROUP BY a 字段1 a 字段2 HAVING Count gt 1 这样即可得到多字段重复数据 2 更新表 去重 做这一步
  • Eclipse 来编译Arduino程序,并烧写Arduino程序

    If you want to build some electronic stuff that needs some programming then Arduino is certainly the best choice It just
  • 推荐系统实战6——EasyRec 搭建WideAndDeep排序模型实现CTR点击平台

    推荐系统实战6 EasyRec 搭建WideAndDeep排序模型实现CTR点击平台 学习前言 EasyRec仓库地址 WideAndDeep实现思路 一 WideAndDeep整体结构解析 二 网络结构解析 1 Embedding层的构建
  • Linux 查找文件位置命令

    查找文件 在linux中 我经常碰到一个问题 就是如何找到某个文件 有时可能是找配置文件 有时是确认软件是否安装等等 精确查找 find name 文件名 在 根目录下按名称查找文件 模糊查找 find name 文件名 在 根目录下按 名
  • 基于引用计数的shared_ptr的简单实现

    简易版的智能指针 多线程中智能指针的读取对象是不安全的 include