C++自定义智能指针

cpp 复制代码
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


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

相关推荐
We་ct1 分钟前
LeetCode 56. 合并区间:区间重叠问题的核心解法与代码解析
前端·算法·leetcode·typescript
Lionel6897 分钟前
分步实现 Flutter 鸿蒙轮播图核心功能(搜索框 + 指示灯)
算法·图搜索算法
无小道9 分钟前
Qt——事件简单介绍
开发语言·前端·qt
小妖66610 分钟前
js 实现快速排序算法
数据结构·算法·排序算法
xsyaaaan13 分钟前
代码随想录Day30动态规划:背包问题二维_背包问题一维_416分割等和子集
算法·动态规划
devmoon14 分钟前
在 Paseo 测试网上获取 Coretime:On-demand 与 Bulk 的完整实操指南
开发语言·web3·区块链·测试用例·智能合约·solidity
kylezhao201931 分钟前
C# 中的 SOLID 五大设计原则
开发语言·c#
王老师青少年编程38 分钟前
2024年信奥赛C++提高组csp-s初赛真题及答案解析(阅读程序第3题)
c++·题解·真题·csp·信奥赛·csp-s·提高组
凡人叶枫1 小时前
C++中输入、输出和文件操作详解(Linux实战版)| 从基础到项目落地,避坑指南
linux·服务器·c语言·开发语言·c++
CSDN_RTKLIB1 小时前
使用三方库头文件未使用导出符号情景
c++