智能指针的实现原理是什么
15 分钟阅读
•
1169 字
+
1326 词
智能指针是利用
RAII机制
来保证资源的自动释放,从而
避免内存泄漏
。
智能指针是利用
RAII机制
来保证资源的自动释放,从而
避免内存泄漏
。
unique_ptr
和
shared_ptr
都是通过
析构函数
来管理资源的释放。当
unique_ptr
超出作用域时,会自动
调用删除操作符
来释放其指向的内存。
std::unique_ptr
通过
删除复制构造函数和复制赋值运算符来确保所有权的唯一性
,但
提供移动构造函数和移动赋值运算符
,允许所有权的转移。
而
shared_ptr
维护
一个指向原始对象的指针
和
一个指向控制块的指针
,这个控制块通常包含
强弱引用计数
和
删除器,分配器
。每当创建一个新的
shared_ptr
或将一个
shared_ptr
赋值给另一个时,引用计数增加。当
shared_ptr
被销毁或通过标准库提供的
reset
成员函数重置时,引用计数减少。当
引用计数降到零时,控制块会释放资源并自我销毁
。
std::weak_ptr
是一种
不拥有对象
的智能指针,它
观察
std::shared_ptr
管理的对象,但
不增加引用计数
。它用于
解决
std::shared_ptr
之间可能产生的
循环引用问题
,因为循环引用会导致引用计数永远不会达到零,从而造成内存泄漏。`
对于引用计数这一变量的存储,是在堆上的,多个shared_ptr的对象都指向同一个堆地址。
为什么尽量使用 make_shared ,make_shared只分配一次内存,通过指针构造shared_ptr有两次分配。当你使用 std::make_shared 时,这两个步骤被合并为一个原子操作,
进行一次内存分配,分配包括对象和控制块的连续内存
。如果使用先new,再传递给shared_ptr的构造函数时,本来new给对象分配了一个空间,然后构造shared_ptr的控制块又分配了一次空间。
智能指针的应用:
自动管理内存分配,延续对象的生命周期,监测对象的存在
作为函数的返回值,函数内部分配了堆的资源,想在类外面使用,并能够在类外面得到正确的释放。
参考答案
-
std::unique_ptr-
unique_ptr代表独占所有权的智能指针,同一时间只能有一个unique_ptr实例指向特定资源。 -
它通过析构函数来管理资源的释放。当
unique_ptr超出作用域时,会自动调用删除操作符来释放其指向的内存。 -
std::unique_ptr通过 删除复制构造函数和复制赋值运算符来确保所有权的唯一性 ,但提供移动构造函数和移动赋值运算符,允许所有权的转移。
-
-
std::shared_ptr-
shared_ptr允许多个指针实例共享对同一资源的所有权,使用 引用计数机制 来跟踪有多少个shared_ptr指向同一资源。 -
内部维护一个控制块,通常包含引用计数和资源的原始指针。每当创建一个新的
shared_ptr或将一个shared_ptr赋值给另一个时,引用计数增加。 -
当
shared_ptr被销毁或通过标准库提供的reset成员函数重置时,引用计数减少。当引用计数降到零时,控制块会释放资源并自我销毁。
-
-
std::weak_ptr-
std::weak_ptr是一种不拥有对象的智能指针,它观察std::shared_ptr管理的对象,但不增加引用计数。 -
它用于解决
std::shared_ptr之间可能产生的循环引用问题,因为循环引用会导致引用计数永远不会达到零,从而造成内存泄漏。
-
总结
unique_ptr
和
shared_ptr
都是通过析构函数来管理资源的释放。当
unique_ptr
超出作用域时,会自动
调用删除操作符
来释放其指向的内存。
std::unique_ptr
通过
删除复制构造函数和复制赋值运算符来确保所有权的唯一性
,但
提供移动构造函数和移动赋值运算符
,允许所有权的转移。而
shared_ptr
维护一个控制块,通常包含
引用计数
和资源的原始指针。每当创建一个新的
shared_ptr
或将一个
shared_ptr
赋值给另一个时,引用计数增加。当
shared_ptr
被销毁或通过标准库提供的
reset
成员函数重置时,引用计数减少。当
引用计数降到零时,控制块会释放资源并自我销毁
。
std::weak_ptr
是一种
不拥有对象
的智能指针,它
观察
std::shared_ptr
管理的对象,但
不增加引用计数
。它用于
解决
std::shared_ptr
之间可能产生的
循环引用问题
,因为循环引用会导致引用计数永远不会达到零,从而造成内存泄漏。`