【c++11】智能指针

智能指针


RAII

RAII(Resource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源(如
存、文件句柄、网络连接、互斥量
等等)的简单技术。
在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在
对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。这种做
法有两大好处:

  • 不需要显式地释放资源。
  • 采用这种方式,对象所需的资源在其生命期内始终保持有效

我们先来看一下下面的代码:

template<class T>
class SmartPtr
{
public:
	SmartPtr(T *ptr)
		:_ptr(ptr)
	{}
	~SmartPtr()
	{
		delete[] _ptr;
		cout << "delete:" << _ptr << endl;
	}
private:
	T* _ptr;
};

int main()
{
	SmartPtr<int> sp1(new int[10]);
	return 0;
}

运行结果:

这样存在了在结束后就会自动释放内存;

但是上述SmartPtr并不能称为智能指针,因为它还不具有指针的行为。指针可以解引用,也可
以通过->去访问所指空间中的内容,因此:AutoPtr模板类中还得需要将* 、->重载下,才可让其
像指针一样去使用;

但是智能指针最大的问题就是拷贝问题:

	int* p1 = new int[10];
	int* p2 = p1;

指针本身就是浅拷贝,p1和p2共同管理同一块资源;

但是这样就会造成析构两次;

那拷贝问题如何解决?

auto_ptr

特点:管理权转移,被拷贝对象被悬空,有风险,不建议使用

最早期提出的是auto_ptr:

	auto_ptr<int> sp1(new int[10]);
	//c++98  转移管理权 --->sp1对象悬空
	auto_ptr<int> sp2(sp1);

unique_ptr

特点:不支持拷贝,没有风险,建议使用

在c++98到c++11之间有一个过度:boost库

在unique_ptr的原理特别的简单粗暴,就是防拷贝:

unique_ptr (const unique_ptr&) = delete;
class A
{
public:
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a1 = 1;
	int _a2 = 1;
};

int main()
{
	unique_ptr<A> sp1(new A);
	//不支持拷贝
	//unique_ptr<A> sp2(sp1);
	A* p = sp1.get();//获得到原身指针;
	cout << p << endl;
	return 0;
}

shared_ptr

但是在一些情况下必须使用拷贝,所以又延伸出了shared_ptr;

shared_ptr就支持拷贝,不会报错:

原理:

下面我们来监视一下引用计数:

make_shared

和shared_ptr主要区别:把资源和计数绑到一起

手撕shared_ptr⭐⭐⭐⭐⭐

手撕shared_ptr主要就是引用计数的处理:

最复杂的是赋值:

release()函数就是析构函数里面的,只不过这里给他重新封装了;

尤其要注意自己给自己赋值的情况⭐⭐⭐⭐

weak_ptr

不支持RAII,不单独管理资源;辅助解决,shared_ptr循环引用,本质赋值或拷贝时,只指向资源,但是不增加引用计数

 

struct Node {
        std::weak_ptr<Node> _next;//改成weak_ptr,weak_ptr不增加节点的引用计数
        std::weak_ptr<Node> _prev;
        int _val;
        ~Node()
        {
                cout << "~Node()" << endl;
        }
};
void test01()
{
        std::shared_ptr<Node> p1(new Node);
        std::shared_ptr<Node> p2(new Node);
        p1->_next = p2;
        p2->_prev = p1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值