unique_ptr
unique_ptr标准库源码
查看C++标准库源代码bits/目录下能找到一个名为unique_ptr.h
的文件,包含了unique_ptr
的实现
unique_ptr的部分源码如下:
1 | template <typename _Tp, typename _Dp = default_delete<_Tp>> |
unique_ptr构造
1 | // 示例 |
参考:std::unique_ptr::unique_ptr - cppreference.com
1 |
|
Effective Modern C++条款21:尽量使用std::make_unique而不直接使用new
1.避免在将new指针赋值智能指针前,程序发生异常,导致赋值失败,则刚刚new出来的指针将无法得到正常释放,从而内存泄漏。
2.使用make_shared只会执行一次内存分配,即将对象及控制块同时分配到一块内存上
但是std::make_unique不允许使用自定义析构器
unique_ptr::get()
通过源码,get函数返回unique_ptr对象底层管理的指针
1 | // 返回智能指针对象底层管理的指针 |
unique_ptr::release()
依然从源码来看,release函数返回了unique_ptr对象底层管理的指针,并且将unique_ptr对象底层管理的指针置空
1 | // 功能和auto_ptr的release函数功能相同,最终只有一个unique_ptr指针指向资源 |
unique_ptr::reset()
从源码来看,reset函数将unique_ptr对象底层管理的指针更换为新的指针,并调用自定义删除器将旧指针指向的资源释放
1 | // 把unique_ptr原来的旧资源释放,重置为新的资源__p |
unique_ptr::swap()
swap交换资源
1 | // unique_ptr::swap example |
unique_ptr自定义删除器
1 | #include <memory> |
unique_ptr 做函数参数
- unique_ptr不能被复制,只可以move,即当要让unique_ptr 的变量做函数参数,直接将变量放在括号里是不可以的,可以用move函数,如果值是引用的话,可以不用move
1 | #include <memory> |
【总结】
1.从上面源码中能明显看到,unique_ptr delete了拷贝构造函数和operator=赋值重载函数,禁止显示的拷贝和赋值,防止了浅拷贝问题的发生。
2.unique_ptr提供了带右值引用参数的拷贝构造和赋值重载函数
3.unique_ptr提供了get()、release()、reset()、swap()等函数,重载了->、*、bool 等运算符
auto_ptr
auto_ptr
是C++98中的一种智能指针,用于提供一种自动内存管理的机制。然而在C++11及以后的版本中,auto_ptr
已经被弃用,并且在C++17中被完全移除了,推荐使用unique_ptr
,shared_ptr
和weak_ptr
等更加安全和高效的智能指针。
auto_ptr处理浅拷贝的问题,是直接把前面的auto_ptr都置为nullptr,只让最后一个auto_ptr持有资源
【示例1】auto_ptr在拷贝构造和赋值重载函数中进行隐式所有权转移
1 | int main() |
【示例2】auto_ptr在容器中使用
1 | int main() |
scoped_ptr
scoped_ptr私有化了拷贝构造函数和operator=赋值函数,从而杜绝了浅拷贝问题的发生,由于不能拷贝和赋值,所有不能应用在容器中。
作者:张泽中
【参考】std::unique_ptr - cppreference.com