C++自定义智能指针

template <class T>
class counted_ptr;

// 智能指针引用计数类
template <class T>
class Ref_Ptr
{
	friend class counted_ptr<T>;
private:
	T* m_pTtr; // 实际的指针
	size_t counted_ptr; // 引用计数
	Ref_Ptr(T* p);
	virtual ~Ref_Ptr();
};

template <class T>
Ref_Ptr<T>::Ref_Ptr(T* p)
{
	m_pTtr = p;
	counted_ptr = 1;
	cout<<"Ref_Ptr() 构造函数调用!"<<endl;
}

template <class T>
Ref_Ptr<T>::~Ref_Ptr()
{
	if (m_pTtr)
	{
		cout<<"~Ref_Ptr() 析构函数函数调用"<<endl;
		delete m_pTtr;
		counted_ptr = 0;
	}
	m_pTtr = NULL;
}

// 智能指针对象
template <class T>
class counted_ptr
{
private:
	Ref_Ptr<T>* m_pRef; // 引用计数
public:
	counted_ptr();
	counted_ptr(T* p);
	~counted_ptr();
	// 重载运算=,将左对象引用计数-1,并判断是否delete;将右对象+1;
	counted_ptr<T> & operator = (counted_ptr& other);
	// 重载指针操作*,->
	T& operator *();
	T* operator ->();
	// 拷贝构造函数,引用计数+1
	counted_ptr(counted_ptr<T>& other);
};
template <class T>
counted_ptr<T>::counted_ptr()
{
	m_pRef = NULL;
}

template<class T>
counted_ptr<T>::counted_ptr(T* p)
{
	m_pRef = new Ref_Ptr<T>(p);
	cout<<"counted_ptr(T* p) 构造函数调用"<<endl;
}

template <class T>
counted_ptr<T>::counted_ptr(counted_ptr<T>& other)
{
	this->m_pRef = other.m_pRef;
	++(m_pRef->counted_ptr);
	cout<<"counted_ptr(& other) 拷贝构造函数被调用,当前引用计数"<< this->m_pRef->counted_ptr<<endl;
}

template <class T>
counted_ptr<T>& counted_ptr<T>::operator=(counted_ptr& other)
{
	// 将右操作对象引用计数+1
	++(other.m_pRef->counted_ptr);

	// 由于左操作对象指向了新对象,需要将操作数-1;
	// 同时也防止了自赋值的方式.
	// 首先要判断这个对象是否已经指向了其他对象,这个很重要!防止左指针对象为null的情况.
	if (this->m_pRef)
	{
		if (--(this->m_pRef->counted_ptr) == 0)
		{
			delete this->m_pRef;
		}
	}

	this->m_pRef = other.m_pRef;
	cout<<"operator = 被调用,当前引用计数"<< this->m_pRef->counted_ptr<<endl;
	return *this;
}

template <class T>
T& counted_ptr<T>::operator *()
{
	return *(m_pRef->m_pTtr);
}

template <class T>
T* counted_ptr<T>::operator->()
{
	return (m_pRef->m_pTtr);
}

template <class T>
counted_ptr<T>::~counted_ptr()
{cout<<"~counted_ptr() 析构函数被调用"<<endl;
	if ((--m_pRef->counted_ptr) == 0)
	{
		cout<<"删除"<<endl;
		delete m_pRef;
		m_pRef = NULL;
	}
	if (m_pRef)
	{
		cout<<"当前引用计数:"<< m_pRef->counted_ptr<<endl;
	}
}


int  main()
{
	counted_ptr<int>* pPtr = NULL;

	{
		counted_ptr<int> g_ptr;
		{
			// 声明一个ptr1智能指针,并测试*运算符
			counted_ptr<int> ptr1(new int(4));
			counted_ptr<int> ptr2;
			cout<< "*ptr1="<< *ptr1<<endl;
			// 将生存期小的ptr1赋值给生存期更大的g_ptr;
			ptr2 = ptr1;
			system("pause");
			g_ptr = ptr1;
			system("pause");
		}
		// new int(4)并没有销毁,因为引用计数还有1个
		cout<<" *g_ptr="<<*g_ptr << endl;
		system("pause");
	}
	system("pause");
	getchar();
	return 0;
}

参考 

std::shared_ptr - cppreference.com


创作不易,小小的支持一下吧!

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

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

相关文章

Golang | Leetcode Golang题解之第200题岛屿数量

题目&#xff1a; 题解&#xff1a; func numIslands(grid [][]byte) int {res : 0for i : 0; i < len(grid); i {for j : 0; j < len(grid[i]); j {if grid[i][j] 1 {resdfs(grid, i, j)}}}return res }func dfs(grid [][]byte, r, c int) {h, w : len(grid), len(gri…

标准版小程序订单中心path审核不通过处理教程

首先看自己小程序是不是已经审核通过并上线状态才在站内信里面提醒的&#xff1f; 如果没有提交过审核&#xff0c;请在提交的时候填写。path地址为&#xff1a;pages/goods/order_list/index 如果是已经上线的小程序&#xff0c;当时没要求填这个&#xff0c;但新的政策要求填…

如何通过Profile快速定位Doris查询瓶颈

1 如何获取profile 参考文档&#xff1a;https://doris.apache.org/zh-CN/docs/query/query-analysis/get-profile 我们时常遇到对应 SQL 执行时间不及预期的情况&#xff0c;为了优化 SQL 达到预期查询时延&#xff0c;通过 Profile 我们能够看出可以做哪些优化。现在说明在…

为何同一PDF文档用不同软件打印效果不同?

通过扫描仪生成的同一PDF文档&#xff0c;同样的设置&#xff0c;为什么别的电脑打出来是白底我的打出来有灰色格子背景&#xff1f;这种情况通常是由于PDF阅读软件的不同造成的差异。 ### 可能的原因和解决方法&#xff1a; 1. **PDF阅读软件的不同**&#xff1a; - **解决方…

小型光纤抗干扰无人机技术详解

一、光纤通信技术应用 光纤通信技术是现代通信技术的重要组成部分&#xff0c;其在小型无人机中的应用为无人机的数据传输带来了革命性的改变。光纤通信具有高速率、大带宽、低损耗和抗电磁干扰等优点&#xff0c;使得无人机在执行任务时能够实时传输高清图像、视频和大量数据…

[JS]BOM操作

介绍 BOM(Browser Object Model)是浏览器对象模型 window对象是一个全局对象, 也是JS中的顶级对象通过var定义在全局作用域中的变量和函数都会变成window对象的属性和方法window对象下的属性和方法调用时一般省略window 间歇函数 定时器 定时器是间歇函数的一种, 可以每个每…

《昇思25天学习打卡营第2天 | 昇思MindSpore张量 Tensor》

第二天学习 1.今天学习了张量 Tensor&#xff0c;了解到Tensor是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数&#xff0c;也是一个特殊的数据结构&#xff0c;与数组和矩阵非常相似。是MindSpore网络运算中的基本数据结构。学些了张量和稀疏张量的属性…

Node版本管理工具 fnm 安装使用

fnm 是一个基于 Rust 开发的 Node 版本管理工具&#xff0c;它的目标是提供一个快速、简单且可靠的方式来管理 Node.js 的不同版本。同时&#xff0c;它是跨平台的&#xff0c;支持 macOS、Linux、Windows。&#x1f680; Fast and simple Node.js version manager, built in R…

五十九周:文献阅读+FiLM

目录 摘要 Abstract 文献阅读&#xff1a;用于长时间序列预测的频率改进的勒让德记忆模型 一、现有问题 二、提出方法 三、相关知识 1、Legendre Projection&#xff08;Legendre投影&#xff09; 2、Fourier Transform&#xff08;傅立叶变换&#xff09; 四、提出的…

文件操作与管理

程序经常需要访问文件和目录&#xff0c;读取文件信息或写入文件信息&#xff0c;在Python语言中对文件的读写是通过文件对象&#xff08;file object&#xff09;实现的。Python的文件对象也称为类似文件对象或流&#xff08;stream&#xff09;&#xff0c;因为Python提供一种…

数据库-数据完整性-用户自定义完整性实验

NULL/NOT NULL 约束&#xff1a; 在每个字段后面可以加上 NULL 修饰符来指定该字段是否可以为空&#xff1b;或者加上 NOT NULL 修饰符来指定该字段必须填上数据。 DEFAULT约束说明 DEFAULT 约束用于向列中插入默认值。如果列中没有规定其他的值&#xff0c;那么会将默认值添加…

ProPainter – AI视频去水印工具,可以去除视频中的静态水印、动态物体/人物等 本地一键整合包下载

ProPainter是一个基于E2FGVI实现的AI视频编辑工具&#xff0c;它可以一键移除视频内的移动物体和水印。这个开源项目提供了一个简单而强大的解决方案&#xff0c;帮助用户轻松编辑和改善视频内容。 项目地址&#xff1a;https://github.com/sczhou/ProPainter 一键包下载&…

【C++初阶 ---- string类】文档介绍 | 容量操作 | 模拟实现

string介绍 前言1. C语言中的字符串2. 标准库中的string类2.1string类对象的容量操作2.2string类对象的访问及遍历操作访问操作 [ ]和at string底层模拟实现 前言 其实 string 就是一个管理字符数组的顺序表&#xff0c;因为字符数组的使用广泛&#xff0c;C 就专门给了一个 s…

mac系统docker默认不支持host主机网络模式

环境描述&#xff1a;在mac系统上安装docker及docker-compose服务&#xff0c;并且打算搭建一个redis集群 问题描述&#xff1a;mac默认不支持host网络模式&#xff0c;导致集群无法通过外部主机访问 具体验证步骤&#xff1a; docker-compose.yml如下&#xff1a; version…

山东省著名烈士孙善师孙善帅故居布展喜添新篇

人海信息网山东讯&#xff08;张春兄、冯爱云&#xff09; “……他们以钢铁般的意志&#xff0c;坚守共产党员的使命&#xff0c;他们就是泺口九烈士的孙善师孙善帅兄弟&#xff01;”6月28日&#xff0c;对于山东省著名烈士孙善师孙善帅故居来说&#xff0c;又是一个不平凡的…

二、安装虚拟机

本篇来源&#xff1a;山海同行 本篇地址&#xff1a;https://shanhaigo.cn/courseDetail/1805875642621952000 本篇资源&#xff1a;以整理到-山海同行 一、官网下载centos7 1. 进入CentOS 官方网站 官方网站&#xff1a;https://www.centos.org/download/ 2. 选择iso 点击下…

基于Delphi编写PC上位机串口通信工具

1&#xff09;Delphi入门级小知识&#xff0c;分享给将要学习或者正在学习Delphi上位机开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 Delphi&#xff0c;是Windows平台下著名的快速应用程…

python(基础语法,pandas,numpy,正则表达式,数据预处理)

python学习推荐网址&#xff1a; 白月黑羽 一、语法基础 目标&#xff1a; • list、tuple、set、dict的基本用法 • 内置函数 len&#xff08;&#xff09;&#xff0c; eval&#xff08;&#xff09;&#xff0c;range&#xff08;&#xff09;&#xff0c;sort&#xff08;…

weiyang**4.合约

通过合约开发&#xff0c;合约编译&#xff0c;SDK配置与业务开发构建了一个基于FISCO BCOS联盟区块链的应用。 官网&#xff1a;开发第一个区块链应用 — FISCO BCOS 2.0 v2.11.0 文档 (fisco-bcos-documentation.readthedocs.io) CSDN&#xff1a;FISCO BCOS开发第一个区块链…

教师资格证(教资)笔试如何备考?含备考资料

教师资格证&#xff08;教资&#xff09;笔试如何备考&#xff1f;含备考资料 前言 教师&#xff0c;一直以来的热门职业&#xff0c;而要成为一名教师&#xff0c;考取教师资格证则是基本条件&#xff0c;那么教资笔试如何备考呢&#xff1f;&#xff0c;这里准备笔试备考攻…