【C++ 智能指针】RAII和四种智能指针你理解吗?
文章目录
- 1. RAII
- 2. 智能指针
1. RAII
-
🐧
RAII (Resource Acquisition Is Initialization)
一种利用对象的生命周期来控制程序资源的技术。 -
🐧 对象构造时获取资源,最后对象析构的时候释放资源。
-
🐧优点:①不需要显示释放资源;②采用这种方式,对象所需的资源在其生命周期内始终保持有效。
2. 智能指针
-
🍎智能指针的原理
1)具有RAII
特性;
2)重载了operator *
和operator ->
,具有像指针一样的行为; -
智能指针的头文件为
#include<memory>
-
🍎智能指针的最大问题: 拷贝问题,因为会析构两次;指针就是浅拷贝问题,共同管理资源;
解决方案:
①auto_ptr
管理权转移,C++98
提出来的,处理方式是转移管理权,此时会导致sp1
对象悬空,因为sp1
不是将亡值,之后会用到,把管理权转移后,后面的访问会非法。
②unique_ptr
- 🐧 同一时刻只能有一个
unique_ptr
指向给定对象,离开作用域时,若其指向对象,则从其所指对象销毁。 - 🍎 定义
unique_ptr
时,需要将其绑定到一个new
返回的指针上。 - 🐧 不支持普通的拷贝和赋值
class A {
public:
~A() {
cout << "~A()";
}
private:
int _a1 = 1;
int _a2 = 1;
};
int main()
{
unique_ptr<A> sp1(new A);
cout << sp1.get() << endl;
A* p1 = sp1.get();
unique_ptr<A> sp2(sp1); // 不支持拷贝
return 0;
}
③ shared_ptr
🐧shared_ptr
的实现机制是在拷贝构造时使用同一份引用计数。
(1)一个模板指针,T* ptr
,指向实际对象
(2)一个引用计数,必须new
出来的,不然会多个shared_ptr
里面会有不同的引用次数而导致多次delete
(3)重载operator *
和operator->
,使得像指针一样使用shared_ptr
(4)重载赋值运算符 =
,如果原来的shared_ptr
已有对象,则让其引用次数减一并判断引用是否为零(是否调用delete
),然后将新的对象引用次数加一
(5)重载析构函数,使引用次数减一并判断引用是否为零(是否调用delete
)
(6)拷贝构造函数,引用次数加一
🍎线程安全问题
(1)同一个 shared_ptr
被多个线程读是安全的;
(2)同一个shared_ptr
被多个线程写是不安全的;
weak_ptr
🍎weak_ptr
是为了配合shared_ptr
而引入的一种智能指针;
它的最大作用是协助shared_ptr
工作,像旁观者一样观测资源的使用情况,但weak_ptr
没有共享资源,它的构造不会引起指针和引用计数增加。
和shared_ptr指向相同内存,shared_ptr
析构之后内存释放,在使用之前使用函数lock()
检查weak_ptr
是否为空指针。