C++_智能指针的基本原理

智能指针的核心思想是将资源(内存)与指针对象的生命周期绑定起来,创建对象的同时立即为其分配资源,对象销毁时立即释放资源。
1、智能指针和资源的绑定
将裸指针和它相关的操作封装成一个类,并在创建对象时必定要调用的构造函数中,分别进行资源的分配和释操作。当然,为了保证对象的操作方式看起来与裸指针相同,这个封装类起码还要重载operator->和operator *
一个简单的,在其生命周期中绑定了一个资源的智能指针类模板My_ptr代码如下:

#include<iostream>
using namespace std;
template<class T>
class My_ptr
{
private:
	T* _ptr;    //裸指针
public:
	My_ptr(T* p):_ptr(p)
	{
		cout << "生成获得资源" << endl;
	}
	T& operator*()    //重载*运算符
	{
		return *_ptr;
	}
	T* operator->()      //重载->运算符
	{
		return _ptr;
	}
	~My_ptr()
	{
		cout << "死前释放资源" << endl;
		//delete _ptr;
	}
};
//测试代码
int main()
{
	int a = 100;
	{
		My_ptr<int> p(&a);       //指针对象p生命期开始
		cout << "打印资源数据" << *p << endl;
	}                           //指针对象p生命周期结束
	cout << "指向对象p生命周期已结束" << endl;
	return 0;
}
//输出结果如下:
生成获得资源
打印资源数据100
死前释放资源
指向对象p生命

在程序设计实践中常常需要多个指针指向(共享)同一个资源,这时,资源的释放就不能单纯地取决于某一个指针对象的生命期。既不能在还有指针使用资源的时候其他指针擅自释放资源,也不能在都不需要资源时没有即时释放资源。
目前,采用指针计数器作为资源管理者,是实现这种智能指针的一种通用实现技术。资源使用者以令计数值加1的方式向管理者登记,以减1的方式进行注销,当计数器值为0时,由管理者进行释放资源

template<typename T>
class Res_Ptr
{
private:
	T* res_p;      //指向资源的指针
	int use_num;         //计数器
	//构造函数
	Res_Ptr(int *p):res_p(p),use_num(1){}
	~Res_Ptr
	{
		delete res_p;
	}
	friend class SharedPtr;   
};

类中以友元类的方式指定了资源使用者的所属类SharePtr。由于这个类的析构函数仅完成了资源释放工作,所以使用者类除了在构造函数中为计数器加1之外,还必须在其析构函数中为计数器减1,并判断是否应该释放资源

template<typename T>
class SharePtr
{
public:
	//构造函数
	SharePtr(T* p, T i): ptr(new Res_Ptr<T>(p)), val(i){}
	//复制构造函数
	SharePtr(const SharePtr& orig) :ptr(orig.ptr), val(orig.val)
	{
		++ptr->use_num;    //指向同一资源指针对象数目加1
	}
	~SharePtr()
	{
		if (--ptr->use_num == 0)   //析构一个指针对象,计数器减去1
			delete ptr;     //如果计数器为0,则删除资源对象
	}
private:
	Res_Ptr<T>* ptr;       //指向资源对象Res_Ptr的指针
	T val;       //可以修改资源数据的变量
};

将上面两个类连起来编写一个程序

#include<iostream>
using namespace std;
template<typename T> class SharePtr;
template<typename T>
//定义计数类模板
class Res_Ptr
{
	friend class SharePtr<T>;
private:
	T* res_p;      //指向资源的指针
	int use_num;         //计数器
	//构造函数
	Res_Ptr(int *p):res_p(p),use_num(1)
	{
		cout << "Res_Ptr构造函数" << endl;
	} 
	~Res_Ptr()
	{
		delete res_p;
		cout << "Res_Ptr析构函数" << endl;
	} 
};
//SharePtr模板声明
template<typename T>
class SharePtr
{
public:
	//构造函数
	SharePtr(T* p, T i): ptr(new Res_Ptr<T>(p)), val(i)
	{
		cout << "SharePtr构造函数" << "use_num = " << ptr->use_num << endl;
	}
	//复制构造函数
	SharePtr(const SharePtr& orig) :ptr(orig.ptr), val(orig.val)
	{
		++ptr->use_num;    //指向同一资源指针对象数目加1
		cout << "SharePtr复制构造函数" << "use_num = " << ptr->use_num << endl;
	}
	~SharePtr()
	{
		cout << "SharePtr析构函数" << "use_num = " << ptr->use_num << endl;
		if (--ptr->use_num == 0)   //析构一个指针对象,计数器减去1
			delete ptr;     //如果计数器为0,则删除资源对象
	}
private:
	Res_Ptr<T>* ptr;       //指向资源对象Res_Ptr的指针
	T val;       //可以修改资源数据的变量
};
//测试代码
int main()
{
	{
		SharePtr<int>hpa = SharePtr<int>(new int(42), 100);    //构造第一个指针对象,指向资源为整型数据42
		{
			SharePtr<int>hpb(hpa);   //复制构造指针对象
			SharePtr<int>hpc(hpb);
			SharePtr<int>hpd = hpa;
		};
		cout << "内层括号结束" << endl;
	}
	cout << "中层括号结束" << endl;
	return 0;
}
//输出结果
Res_Ptr构造函数
SharePtr构造函数use_num = 1
SharePtr复制构造函数use_num = 2
SharePtr复制构造函数use_num = 3
SharePtr复制构造函数use_num = 4
SharePtr析构函数use_num = 4
SharePtr析构函数use_num = 3
SharePtr析构函数use_num = 2
内层括号结束
SharePtr析构函数use_num = 1
Res_Ptr析构函数
中层括号结束

在C++11的标准中也定义了三大智能指针,uniquer_ptr、shared_ptr和weak_ptr,具体使用方式可以参考C++ Primer 5th

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
unique_ptr 是 C++11 中引入的智能指针,用于管理动态分配的对象。 unique_ptr 的特性是:它是唯一拥有(unique ownership)被管理对象的智能指针,也就是说,同一时间只能有一个 unique_ptr 指向一个对象。当 unique_ptr 被销毁时,它会自动释放所管理的对象内存。 下面是 unique_ptr 的简单实现: ```cpp template <typename T> class unique_ptr { public: unique_ptr(T* ptr = nullptr) : m_ptr(ptr) {} ~unique_ptr() { delete m_ptr; } unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; unique_ptr(unique_ptr&& other) noexcept : m_ptr(other.m_ptr) { other.m_ptr = nullptr; } unique_ptr& operator=(unique_ptr&& other) noexcept { if (this != &other) { delete m_ptr; m_ptr = other.m_ptr; other.m_ptr = nullptr; } return *this; } T* get() const { return m_ptr; } T* operator->() const { return m_ptr; } T& operator*() const { return *m_ptr; } private: T* m_ptr; }; ``` 这是一个简化版本的 unique_ptr,它包含了基本的功能,如构造函数、析构函数、移动构造函数、移动赋值运算符,以及 get()、operator->() 和 operator*() 方法。 需要注意的是,这个实现并不完整,只是为了演示 unique_ptr 的基本原理和用法。实际使用时,应该考虑更多的细节,如空指针检查、自定义删除器等。另外,C++11 中已经提供了标准库中的 unique_ptr 实现,我们通常会使用标准库中的智能指针而不是自己实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值