C++模拟标准库智能指针shared_ptr

利用模板模拟标准库智能指针代码如下:

#pragma once

#ifndef SHARED_PTR_H
#define SHARED_PTR_H

#include <iostream>
#include <functional>
///书写自己版本的Shared_ptr
template<typename _Ty>
class Shared_ptr
{
	using _Del = void(*)(_Ty*);			//删除器类型别名
public:
	//typedef  void(*)(_Ty*) _Del;		//提供的删除器类型

	/// Construct function	
	Shared_ptr() : element(nullptr), use(new int(0)) {}			//默认构造
	Shared_ptr(_Ty* p) :element(p), use(new int(1)) {}		//传递指针构造
	Shared_ptr(_Ty* p, _Del d) : element(p), use(new int(1)) { del = d; }			//传递一个自定义的删除函数
	Shared_ptr(const Shared_ptr& rhs) :element(rhs.element), use(rhs.use) { ++*use; }		//拷贝构造,引用计数递增
	Shared_ptr(Shared_ptr&& rhs) noexcept : element(rhs.element), use(rhs.use) { rhs.element = rhs.use = nullptr; }	//移动构造

	///重载运算符
	Shared_ptr& operator=(const Shared_ptr& rhs);		//拷贝赋值
	Shared_ptr& operator=(Shared_ptr&& rhs) noexcept;	//移动赋值
	_Ty& operator*();					//解引用运算符
	const _Ty& operator*() const;		//解引用常量版本
	_Ty* operator->() const;			//重载箭头运算符	


	///成员函数
	int use_count() const { return *use; }		//返回正在使用的计数
	void release();								//引用计数递减1,如果为0,则释放占用的内存
	void reset(const Shared_ptr& rhs);			//重新设置指针指向一个Shared_ptr对象
	void reset(_Ty* p);							//设置指针指向一个动态分配的指针
	void reset(_Ty* p, _Del d);					//设置一个指针和自定义删除类型
	bool unique() const { return *use == 1; }	//检查当前是否独享对象
	_Ty* get() const { return element; }		//返回内置指针类型

	///析构函数
	~Shared_ptr() { free(); }			//析构函数负责调用free函数
private:
	static std::function<void(_Ty*)> del;		//用于保存用户提供的删除操作

	_Ty* element;		//绑定的元素
	int *use;		//使用计数。检查当前有多少个用户正在使用该指针


	///工具函数 负责释放内存
	void free();
};
template<typename _Ty>	std::function<void(_Ty*)> Shared_ptr<_Ty>::del = nullptr;		//类外定义静态成员	


template<typename _Ty>
Shared_ptr<_Ty>& Shared_ptr<_Ty>::operator=(const Shared_ptr<_Ty>& rhs)		//拷贝赋值
{
	//处理自赋值的情况
	++(*rhs.use);		//先递增右侧对象引用计数
	free();				//递减本对象的引用计数

	///更新引用计数
	use = rhs.use;
	element = rhs.element;

	return *this;
}
template<typename _Ty>
Shared_ptr<_Ty>& Shared_ptr<_Ty>::operator=(Shared_ptr<_Ty>&& rhs) noexcept		//使用移动赋值
{
	if (this != &rhs)		//检查自赋值情况
	{
		use = rhs.use;
		element = rhs.element;
		rhs.element = rhs.use = nullptr;		//使其进入可析构状态
	}
	return *this;
}
template<typename _Ty>
_Ty& Shared_ptr<_Ty>::operator*()			//解引用运算符
{
	return *element;		//返回解引用之后的对象
}
template<typename _Ty>
const _Ty& Shared_ptr<_Ty>::operator*() const
{
	return *element;		//返回常量解引用
}

template<typename _Ty>
inline _Ty * Shared_ptr<_Ty>::operator->() const
{
	return element;
}

template<typename _Ty>
inline void Shared_ptr<_Ty>::release()
{
	free();		//调用free函数进行释放。如果当前的引用计数为1或者为0的话,那么旧内存被释放。否则只是引用计数-1

	element = use = nullptr;		//使指针进行安全模式,防止二次析构
}
template<typename _Ty>
inline void Shared_ptr<_Ty>::reset(_Ty * p)			//使用动态指针进行重置
{
	free();		//调用free函数 递减引用计数

	///更新指针和引用计数
	use = new int(1);
	element = p;
}
template<typename _Ty>
inline void Shared_ptr<_Ty>::reset(_Ty * p, _Del d)
{
	free();		//递减引用计数 必要时释放内存

	use = new int(1);
	element = p;
	del = d;	// 设置自定义删除器
}
template<typename _Ty>
inline void Shared_ptr<_Ty>::reset(const Shared_ptr<_Ty>& rhs)
{
	*this = rhs;		//直接可以调用赋值函数完成
}

template<typename _Ty>
inline void Shared_ptr<_Ty>::free()
{
	if (--*use <= 0) {			//当引用计数为0或者小于0的时候进行释放元素,小于0的情况是该类使用了默认构造或者是释放了内存
		
		///如果用户提供了删除器的话,使用用户提供的删除器进行删除
		del ? del(element) : delete element;
		delete use;
		std::cout << "Delete success" << std::endl;		//测试语句
	}
}

#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

David_TD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值