共享型智能指针的实现share_pointer

2023-10-27

智能指针是一个类,它产生的是一个类对象,而不是一个原生的指针对象,但是为了减少类对象与针对对象使用的差异性,所以share_ptr类故意重载了两种常见的指针操作符: *和->。从而share_ptr与普通指针使用方式一样。简言之,就是share_ptr生成的一个包含类型指针容器对象,它封装了指针对象,对指针对象负全责,包括生成、释放等。

智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象

  • 下面代码为share_pointer的实现,包括:
    • 默认构造函数
    • 显式定义的自定义构造函数
    • 拷贝构造函数
    • 移动构造函数
    • 拷贝赋值函数
    • 移动赋值函数
    • *运算符
    • ->运算符
    • 三个版本的reset函数
  • 计数变量设为指针,主要是因为计数是共有的,这样一方面可以节省内存,另一方面可以达到管理共有变量的目的
  • destroy函数delete指针时不调用删除器
  • 删除器为一个可调用模板,在调用函数中可以用function定义其模式
#ifndef SHAREPOINTER_H
#define SHAREPOINTER_H

#include "DebugDelete.h"
#include <functional>
#include <iostream>
//1.模板成员函数知道使用时编译器才去编译
template<typename T>class share_pointer
{
public:

    //默认构造函数
    share_pointer(){} 


    //显式定义构造函数,传递指针管理类型和删除器对象两个形参
    explicit share_pointer(T *t, std::function<void(T*)> d = DebugDelete()):t(t),count(new size_t(1)),Deleter(d){}


    //拷贝构造函数
    share_pointer(share_pointer &sp):count(sp.count),t(sp.t),Deleter(sp.Deleter){
        std::cout << "copy" << std::endl;
        ++*count;
    }


    //移动构造函数,share_pointer<int> m(share_pointer<int>(new int(30)))调用移动构造函数,若无,则调用拷贝构造函数
    share_pointer(share_pointer &&sp):count(sp.count),t(std::move(sp.t)),Deleter(std::move(sp.Deleter)){
        std::cout << "moving" << std::endl;
        sp.t = nullptr;
    }


    //赋值构造函数
    share_pointer &operator=(share_pointer &sp);


    //返回指针指向的值
    T& operator*() const {return *t;}


    //重载->
    T* operator->() const {return &this->operator*();}

    //reset
    void reset(){
        deconstructor();
    }

    void reset(T* p){
        if (t)
        {
            deconstructor();
            t = p;
            count = new size_t(1);
        }
    }

    void reset(T* p,std::function<void(T*)> d){
            reset(p);
            Deleter = d;
    }



private:

    std::size_t *count;//6.计数为不同对象的公共变量,固定义一个指针,指向共有内存

    T *t ;

    std::function<void (T*)> Deleter;

    void deconstructor();
};

template<typename T> 
inline void share_pointer<T>::deconstructor(){
    if(t)
    {
        --*count;
        if (*count == 0)
        {
            Deleter(t);
            delete count;
        }
    }
    t = nullptr;
    count = nullptr;
}

template<typename T>
inline share_pointer<T> &share_pointer<T>::operator=(share_pointer &sp){
    ++(*sp.count);
    deconstructor();
    count = sp.count;
    t = sp.t;
    Deleter = sp.Deleter;
    return *this;
}

#endif
  • 下面代码为删除器代码
#ifndef DEBUGDELETE_H
#define DEBUGDELETE_H
#include <iostream>
 class DebugDelete
{
public:
    DebugDelete(std::ostream &s = std::cerr):os(s){}  //流无法被拷贝
    template<typename T> void operator()(T* t)const
    {
        os << "deleting ptr" << std::endl;
        //std::cout << "t:" << t <<" &t:"<< &t <<" *t:" <<*t << std::endl;
        delete t;
        //std::cout << "t:" << t <<" &t:"<< &t <<" *t:" <<*t << std::endl;
    }
private:
    std::ostream &os;//流无法被拷贝
 };
#endif
  • 下面为主函数
#include "DebugDelete.h"
#include <iostream>
#include "share_pointer.h"
#include <functional>
#include <utility>
#include <iostream>
#include <string>

int _tmain(int argc, _TCHAR* argv[])
{
    share_pointer<int> p(new int(20));
    share_pointer<int> s(new int(30));
    share_pointer<int> q(s);
    s = p;
    share_pointer<int> m(share_pointer<int>(new int(30)));
    int mm = *m;
    share_pointer<std::string> n(share_pointer<std::string>(new std::string("hello")));
    n.reset();
    m.reset(new int(32));
    p.reset(new int(43),DebugDelete());

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

共享型智能指针的实现share_pointer 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐

  • OPC服务器简介和入门介绍

    什么是OPC OPC代表OLE 对象链接和嵌入 过程控制 OPC是最流行的数据连接标准 用于在控制器 设备 应用程序和其他基于服务器的系统之间进行通信 而无需进入数据传输的自定义驱动程序 工厂自动化系统或过程由来自不同供应商或供应商的不同协
  • 动态主机配置协议DHCP

    文章目录 一 DHCP介绍 二 DHCP工作原理 三 DHCP实验 eNSP 四 总结 一 DHCP介绍 DHCP 全称动态主机配置协议 Dynamic Host Configuration Protocol 在大型企业网络中 会有大量的主
  • python hook android_[原创]初识Frida--Android逆向之Java层hook (一)

    博客同步 访问 0x00 文中用到的工具Frida jadx gui 一个强大的android反编译工具 genymotion模拟器 Python2 7以及frida python库 radare2 反汇编器 pycharm 0x01 ho
  • 安卓APP_ 布局(1)—— LinearLayout

    摘自 安卓APP 布局 1 LinearLayout 作者 丶PURSUING 发布时间 2021 04 05 16 46 22 网址 https blog csdn net weixin 44742824 article details
  • python决策树算法代码_Python3.0 实现决策树算法的流程

    决策树的一般流程 检测数据集中的每个子项是否属于同一个分类 if so return 类标签 Else 寻找划分数据集的最好特征 划分数据集 创建分支 节点 from math import log import operator 生成样本
  • ASP.NET微信公众号开发实记之一 接入配置

    第一步 填写服务器配置 登录微信公众平台官网后 在公众平台后台管理页面 开发者中心页 点击 修改配置 按钮 填写服务器地址 URL Token和EncodingAESKey 其中URL是开发者用来接收微信消息和事件的接口URL Token可
  • 【Unity 3D】图形界面GUI的讲解及在C#中实现用户登录界面的实战(附源码)

    需要源码请点赞关注收藏后评论区留言并且私信 在游戏开发过程中 游戏界面占据了非常重要的地位 玩家启动游戏的时候 首先看到的就是游戏的UI 其中包含图片 按钮和高级控件等等 UGUI和GUI是Unity 3D中最常用的两个UI系统 一 GUI
  • VMware workstation搭建华为FusionCompute实验环境(五)保姆级安装教程,可运行虚拟机

    VMware安装VRM 1 打开VMware 点击文件 选择新建虚拟机 2 选择 自定义 3 硬件兼容性保持默认 4 选择稍后安装操作系统 5 操作系统选择 ESXI 6 输入虚拟机名称及虚拟机保存位置 7 配置处理器 最少4个 8 配置内
  • 低功耗设计及其UPF实现第一节

    第一节 低功耗设计的基本单元和概念 大家好 最近疫情宅家 工作没有那么忙 所以写一下之前从事过的低功耗设计并和大家分享 希望大家多多提出不足 本次总结一共分为若干小节 还没定 我会从最最基础的低功耗的概念和器件开始分享 尽量全部说干货 不过
  • 暑假补卷2——进程控制:

    进程地址空间 接进程概念 写时拷贝 通常 父子代码共享 父子再不写入时 数据也是共享的 当任意一方试图写入 便以写时拷贝的方式各自一份副本 具体见下图 fork常规用法 一个父进程希望复制自己 使父子进程同时执行不同的代码段 例如 父进程等
  • 晶振/晶体布线原则

    1 晶振布放和走线同IC在相同层 50欧姆走线 布线层到参考层间挖开GND 晶振模块远离其他器件 2 晶体模块参考层尽量使用完整GND层 没有完整GND层可用 也要在晶振下面完全铺地 3 走线仅可能短 两根线尽量等长且尽量紧密耦合 4 将负
  • 学生选课系统项目设计报告

    设 计 报 告 报告题目 学生选课系统的数据库设计 摘 要 在当下疫情肆虐的时期 线上教学成为了主流方式 各种教学活动都转为线上 网上选课系统成为学生课程分配的主要方式 传统的选课管理模式已经无法满足当前的实际需求 为此 我们开发了学生选课
  • 2023年最新最全软件测试用例大全,轻松学会测试用例,有手就行

    一 概念 测试用例的基本概念 测试用例 Test Case 是为了实施测试而向被测试的系统提供的一组集合 这组集合包含 测试环境 操作步骤 测试数据 预期结果等要素 主要步骤 测试环境 测试步骤 测试数据 预期结果 网易邮箱注册成功测试用例
  • torchvision中的resnet的实现

    D pythonCodes 深度学习实验 经典分类网络 6 ResNet resnet手动实现实验 一 ResNet网络模型详解 1 1 整体结构 可以看到 resnet34主要就是由layer1 4组成 而这4个layer分别就是由3 4
  • Web前端iframe使用以及页面通信postmessage

    iframe基本内涵 通常我们使用iframe直接直接在页面嵌套iframe标签指定src就可以了 iframe常用属性 1 frameborder 是否显示边框 1 yes 0 no 2 height 框架作为一个普通元素的高度 建议在使
  • AppsFlyer 研究(六) 域名及用户邀请归因

    一 AppsFlyer涉及的域名 1 https conversions appsflyer com 该域名用于SDK上报App首次打开的session数据 包含用户的设备id 供AF归因 2 https gcdsdk appsflyer
  • 百人计划 图形1.4 PC手机图形API介绍作业/个人笔记

    作业部分 1 本人对Vulkan不了解 下述文字根据网上资料搜集总结而来 如日后有新的想法将更新在此段文字之后 Vulkan优点是轻薄 降低CPU的开销 缺点是相对繁琐 接口多概念多 Vulkan让我想到houdini 功能强大 建模特效程
  • 2014-10 u-boot make过程分析

    Based on u boot 2014 10 当我们已经做完make xxx defconfig后 这个流程可以参看 2014 10 u boot make xxx defconfig 过程分析 在源码顶层目录生成 config文件 然后
  • $(...).datetimepicker is not a function

    1 jQuery版本不一致 2 datetimepicker js放在最后引入 这种要先引入JS或者JQ 最后才引入这个时间JS文件
  • 共享型智能指针的实现share_pointer

    智能指针是一个类 它产生的是一个类对象 而不是一个原生的指针对象 但是为了减少类对象与针对对象使用的差异性 所以share ptr类故意重载了两种常见的指针操作符 和 gt 从而share ptr与普通指针使用方式一样 简言之 就是shar