【C++】C++中的四种个智能指针.md
智能指针的出现的目的就是为了解决c++中出现异常安全资源管理问题,智能指针的实现原理是依据RAII机制(Resource Acquisition Is Initialization),这是的智能指针本质上是一个对象,行为表现上是一个指针。
智能指针都是类模板使用时是必须指定类型参数的,如:auto_ptr<int> ptr
1.auto_ptr
- auto_ptr采用所有权的模式,指针内不做引用计数,因此一个对象只能由一个auto_ptr指针所拥有,在给其他auto_ptr指针赋值时,所有权会转移
- auto_ptr中使用delete来释放资源,所以auto_ptr不能指向数组,因为数组的释放使用的是delete[]
- auto_ptr指针的判空使用auto_ptr.get()==NULL来判断
auto_ptr是C++98中的标准,在C++11中已经被弃用。
auto_ptr由于是所有权模式,所在在auto_ptr做参数时,会转移所有权,即将函数外的auto_ptr的所有权转义给函数内的auto_ptr的所有权,如果函数内不做所有权转移的话,函数外的auto_ptr将变为空指针,而导致引用出错。如:
不转移所有权
1 |
|
输出结果:
1 |
|
转移所有权
1 |
|
输出结果:
1 |
|
2.unique_ptr
unique_ptr是C++11中对C++98中的auto_ptr的替换与强化
unique_ptr也是使用独占所有权模式,即一个unique_ptr指针指向一个对象后,不可以在把这个对象赋予给另一个unique_ptr指针,后来出于一些考虑C++又提供了srd::move()函数来做所有权的移交,被移交所有权的unique_ptr指针会指向空,这时再使用这个指针就会报错
unique_ptr指针支持直接使用==判空,如:
1 |
|
当然unique_ptr依旧支持unique_ptr.get()==NULL来判空。
- 当unique_ptr作为实参进行传递时,必须使用std::move()来移交所有权,这是unique_ptr的独占所有权性质决定的。如:
1 |
|
3.shared_ptr
shared_ptr指针支持一个对象被多个指针指向
shared_ptr使用计数机制来记录对象被多少个shared_ptr指针所指向,可以使用share_ptr.reset()函数来释放当前指针,对象的引用计数减一,当引用计数减为0时,释放对象资源
可以使用shared_ptr.use_count()来获取当前对象的引用计数
我们来看一个例子:
1 |
|
输出结果:
1 |
|
咦!为什么引用计数count_1是3呢?这是因为在函数内形参shared_ptr<int> ptr
也指向了同一个对象。而当函数Test结束形参指针释放,同时又使用reset()函数释放pt指针,所以count_2:1
4.weak_ptr
虽然shared_ptr使用起来更接近C的原生指针,但是当shared_ptr指针作为类成员时,可能会出现互相引用的而形成死锁,导致引用计数永远无法将为0的现象,如:
1 |
|
这种情况是,pa是指向A类型的shared_ptr指针指向A类型对象,而pa指向的内存里面又有一个shared_ptr指针指向B类型对象,同理pb也是如此,这样就导致,当A要被释放时,要先释放B,而B要释放时又要先释放A,如此便形成了一个互相等待的死循环。weak_ptr的存在就是为了解决这种问题。
weak_ptr指针是一种弱引用,它指向对象和释放时不会引起引用计数的变化,这样便可以打破shared_ptr的这种死循环了,我们将上面的代码改成如下,就可以解死循环了。
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!