波奇学C++:智能指针(二):auto_ptr, unique_ptr, shared_ptr,weak_ptr

C++98到C++11:智能指针分为auto_ptr, unique_ptr, shared_ptr,weak_ptr,这几种智能都是为了解决指针拷贝构造和赋值的问题

auto_ptr:允许拷贝,但只保留一个指向空间的指针。

管理权转移,把拷贝对象的资源管理权转移给拷贝对象,导致被拷贝对象悬空,不能访问出问题 ap1置空

auto_ptr<Test> ap1(new Test());
auto_ptr<Test> ap3 = ap1;
// ap1=nullptr

如果不置空就会导致对象调用析构函数时,空间会被释放两次。但会导致ap1无法再使用。

模拟auto_ptr

template<class T>
class AutoPtr
{
public:AutoPtr(T* ptr):_ptr(ptr){}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}~AutoPtr(){cout << "delete pointer" << _ptr << endl;delete _ptr;}AutoPtr(AutoPtr<T>& ap):_ptr(ap._ptr){ap._ptr = nullptr;}
private:T* _ptr;
};

 unique_ptr: 禁止拷贝

unique_ptr<A> up1(new A());
unique_ptr<A> up3=up1// 报错

模拟实现unique_ptr

template<class T>
class UniquePtr
{
public:UniquePtr(T* ptr):_ptr(ptr){}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}~UniquePtr(){cout << "delete pointer" << _ptr << endl;delete _ptr;}UniquePtr(const UniquePtr<T>& up) = delete; // 禁止拷贝构造UniquePtr<T>& operator=(const UniquePtr<T>& up) = delete; //禁止默认生成赋值重载函数
private:T* _ptr;
};

shared_ptr:支持拷贝,无法解决循环引用

shared_ptr通过引用计数来防止被多次析构

引用计数

用一个变量来记录指向空间的指针数,当一个智能指针释放时,变量数值减一,当数值为0时才释放空间。

模拟share_ptr的实现

template<class T>
class SharedPtr
{
public:SharedPtr(T* ptr):_ptr(ptr),_pcount(new int(1)){}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}~SharedPtr(){if (--(*_pcount) == 0){cout << "delete pointer" << _ptr << endl;delete _ptr;delete _pcount;}}private:T* _ptr;int* _pcount;
};

 shared_ptr的拷贝构造

SharedPtr(const SharedPtr<T>& sp):_ptr(sp._ptr),_pcount(sp._pcount){(*_pcount)++;}

shared_ptr的赋值重载

SharedPtr<T>& operator=(const SharedPtr<T>& sp){if (_ptr==sp._ptr){return *this;}if (*_pcount == 1){~SharedPtr();}else{(*_pcount)--;}*(sp._pcount)++;_pcount = sp._count;_ptr = sp._ptr;return *this;}

 循环引用问题

class Test
{
public:Test(){cout << "构造函数"<<" "<<this << endl;}Test* fun(){return this;}~Test(){cout << "析构" << endl;}};
struct Node
{Test test;shared_ptr<Node> _next;shared_ptr<Node> _prev;
};
int main()
{shared_ptr<Node> sp1(new Node);shared_ptr<Node> sp2(new Node);sp1->_next = sp2;sp2->_prev=sp1return 0;
}

当sp1 和sp2析构时,引用计数减为1

当要释放左边空间->释放右边空间的_prev->释放左边的_next->释放左边的空间。

释放左边空间->释放左边空间

形成死循环无法解决。

weak_ptr:解决shared_ptr循环引用问题,不属于RAII智能指针

struct Node
{Test test;weak_ptr<Node> _next;weak_ptr<Node> _prev;
};

weak_ptr:解决原理不增加引用计数

template<class T>
class WeakPtr
{
public:WeakPtr():_ptr(nullptr){}WeakPtr(const SharedPtr<T>& sp):_ptr(sp._ptr){}WeakPtr<T>& operator= (SharedPtr<T>& sp){_ptr = sp.get();return *this;}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}
private:T* _ptr;
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue中实现纯数字键盘

一、完整 代码展示 <template><div class"login"><div class"login-content"><img class"img" src"../../assets/image/loginPhone.png" /><el-card class"box-card"><div slot"hea…

阵列信号处理---频率-波数响应和波束方向图

波束延迟求和器 阵列是由一组全向阵元组成&#xff0c;阵元的位置为 p n p_n pn​&#xff0c;如下图所示&#xff1a; 阵元分别在对应的位置对信号进行空域采样&#xff0c;这样就产生了一组信号信号为 f ( t , p ) f(t,p) f(t,p),具体表示如下&#xff1a; f ( t , p ) [ f…

C++入门篇(零) C++入门篇概述

目录 一、C概述 1. 什么是C 2. C的发展史 3. C的工作领域 4. C关键字(C98) 二、C入门篇导论 一、C概述 1. 什么是C C是基于C语言而产生的计算机程序设计语言&#xff0c;支持多重编程模式&#xff0c;包括过程化程序设计、数据抽象、面向对象程序设计、泛型程序设计和设计模式…

SQL Server 2016(创建数据库)

1、实验环境。 某公司有一台已经安装了SQL Server 2016的服务器&#xff0c;现在需要新建数据库。 2、需求描述。 创建一个名为"db_class"的数据库&#xff0c;数据文件和日志文件初始大小设置为10MB&#xff0c;启用自动增长&#xff0c;数据库文件存放路径为C:\db…

Ubuntu系统CLion安装与Ubuntu下菜单启动图标设置

Ubuntu系统CLion安装 pycharm 同理。 参考官网安装过程&#xff1a;官网安装过程 下载linux tar.gz包 # 解压 sudo tar -xzvf CLion-*.tar.gz -C /opt/ sh /opt/clion-*/bin/clion.sh其中第二个命令是启动CLion命令 clion安装完以后&#xff0c;不会在桌面或者菜单栏建立图…

大学里学编程,为什么这么难?

在大学学习计算机专业&#xff0c;为何很多同学觉得编程学得不顺心呢&#xff1f;许多同学会有这种感觉&#xff0c;在上大学里的计算机专业课程时&#xff0c;听得头都大了&#xff0c;但是真正要写代码&#xff0c;却不知道从哪里开始&#xff0c;或是觉得&#xff0c;大学里…

05:2440----代码重定义

目录 一&#xff1a;引入 1&#xff1a;基本概念 2&#xff1a;NAND启动 3&#xff1a;NOR启动 4:变量 5&#xff1a;实验证明 A:代码makefile B:NOR启动 C:NAND启动 D:内存空间 二&#xff1a;链接脚本 1:NOR 2:NAND 3:解决方法 A:尝试解决 B:方法一解决 A:简…

【SparkSQL】SparkSQL的运行流程 Spark On Hive 分布式SQL执行引擎

【大家好&#xff0c;我是爱干饭的猿&#xff0c;本文重点介绍、SparkSQL的运行流程、 SparkSQL的自动优化、Catalyst优化器、SparkSQL的执行流程、Spark On Hive原理配置、分布式SQL执行引擎概念、代码JDBC连接。 后续会继续分享其他重要知识点总结&#xff0c;如果喜欢这篇文…

Echarts大屏可视化_05 折线图的定制开发

继续跟着pink老师学习Echarts相关内容&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 折线图1 1.引入 折线图选取示例地址 标题没有用到就给他删了 直接引入 注意这里是line下面的chart 获取dom元素一定不…

吉他初学者学习网站搭建系列(4)——如何查询和弦图

文章目录 背景实现ChordDbvexchords 背景 作为吉他初学者&#xff0c;如何根据和弦名快速查到和弦图是一个必不可少的功能。以往也许你会去翻和弦的书籍查询&#xff0c;像查新华字典那样&#xff0c;但是有了互联网后我们不必那样&#xff0c;只需要在网页上输入和弦名&#…

POSTGRESQL中如何利用SQL语句快速的进行同环比?

1. 引言 在数据驱动的时代&#xff0c;了解销售、收入或任何业务指标的同比和环比情况对企业决策至关重要。本文将深入介绍如何利用 PostgreSQL 和 SQL 语句快速、准确地进行这两种重要分析。 2. 数据准备 为了演示&#xff0c;假设我们有一张 sales 表&#xff0c;存储了销…

【PyTorch】线性回归

文章目录 1. 代码实现1.1 一元线性回归模型的训练 2. 代码解读2.1. tensorboardX2.1.1. tensorboardX的安装2.1.2. tensorboardX的使用 1. 代码实现 波士顿房价数据集下载 1.1 一元线性回归模型的训练 import numpy as np import torch import torch.nn as nn from torch.ut…

深度学习:什么是知识蒸馏(Knowledge Distillation)

1 概况 1.1 定义 知识蒸馏&#xff08;Knowledge Distillation&#xff09;是一种深度学习技术&#xff0c;旨在将一个复杂模型&#xff08;通常称为“教师模型”&#xff09;的知识转移到一个更简单、更小的模型&#xff08;称为“学生模型”&#xff09;中。这一技术由Hint…

二叉树遍历及应用

文章目录 前言构建二叉树前序遍历中序遍历后序遍历二叉树的结点个数二叉树的叶节点个数二叉树的高度二叉树第K层结点个数 前言 二叉树的遍历及应用主要是运用了递归、分治的思想。在这一篇文章&#xff0c;小编将介绍二叉树的前序遍历、中序遍历、后序遍历&#xff0c;求二叉树…

Fiddler抓包工具之fiddler设置手机端抓包

fiddler设置手机端抓包 安卓手机抓包 第一步&#xff1a;配置电脑和安卓的相关设置 1、手机和fiddler位于同一个局域网内&#xff1b;首先从fiddler处获取到ip地址和端口号&#xff1a; &#xff0c;点击online&#xff0c;最后一行就是ip地址 2、路径&#xff1a;Tools》O…

【ASP.NET CORE】数据迁移 codefirst

已经写好实体类&#xff0c;使用add-migration生成数据迁移语句&#xff0c;注意如果项目中有多个dbcontext需要使用 -context 名称&#xff0c;指定下需要使用的dbcontext add-Migration Address -context mvcsqlcontext运行后会生成两个文件 2. 使用Update-Database语句更…

Web自动化测试详解

做测试的同学们都了解&#xff0c;做Web自动化&#xff0c;我们主要用Selenium或者是QTP。 有的人可能就会说&#xff0c;我没这个Java基础&#xff0c;没有Selenium基础&#xff0c;能行吗&#xff1f;测试虽然属于计算机行业&#xff0c;但其实并不需要太深入的编程知识&…

C++学习之路(十六)C++ 用Qt5实现一个工具箱(为屏幕颜色提取功能增加一个点击复制的功能)- 示例代码拆分讲解

上篇文章&#xff0c;我们用 Qt5 实现了在小工具箱中添加了《颜色代码转换和屏幕颜色提取功能》功能。今天我们把屏幕颜色提取的功能再扩展一下&#xff0c;让它可以点击复制吧。下面我们就来看看如何来规划开发这样的小功能并且添加到我们的工具箱中吧。 老规矩&#xff0c;先…

数字图像处理(实践篇)十三 数据增强之给图像添加噪声!

目录 一 涉及的函数 二 实践 一 涉及的函数 skimage.util.random_noise( ) skimage.util.random_noise(image, modegaussian, seedNone, clipTrue, **kwargs) 函数的功能&#xff1a;为浮点型图片添加各种随机噪声。 输入&#xff1a; ①image&#xff1a;输入图像&…

【C/C++笔试练习】公有派生、构造函数内不执行多态、抽象类和纯虚函数、多态中的缺省值、虚函数的描述、纯虚函数的声明、查找输入整数二进制中1的个数、手套

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;公有派生&#xff08;2&#xff09;构造函数内不执行多态&#xff08;3&#xff09;抽象类和纯虚函数&#xff08;4&#xff09;多态中的缺省值&#xff08;5&#xff09;程序分析&#xff08;6&#xff09;重载和隐藏&a…