-
总览
-
轻量级
- 行为基本和原始指针相同.
-
大小
- 默认:
delete
析构,大小和原始指针一样.
- 默认:
-
实现
- 支持构造和移动,不支持拷贝.
- 数据采用
tuple
组合,组合类之间采用继承的方式.
-
析构
- 默认和自定义.
-
使用
- 工厂.
- 不完整的成员指针变量.
-
转换
unique_ptr
独占.- 移动转化为
shared_ptr
也是可以的.
-
-
轻量级
-
默认
-
使用
delete
析构. -
大小和原始指针一样.
-
-
分析
template <typename _Tp, typename _Dp = default_delete<_Tp>> class unique_ptr
-
可以看到
default_delete
是默认的析构.
template<typename _Tp> struct default_delete { constexpr default_delete() noexcept = default;void operator()(_Tp* __ptr) const{ delete __ptr;} };
-
默认析构是一个可调用对象.无数据.
template <typename _Tp, typename _Dp> class __uniq_ptr_impl { private:tuple<pointer, _Dp> _M_t; };__uniq_ptr_impl<_Tp, _Dp> _M_t;
-
unique_ptr
的唯一成员变量,_M_t
. -
实际是
tuple
的封装,tuple
则是以继承的形式实现. -
所以默认
delete
是空类,指针继承还是空的.大小不变,多出来了一些代码而已.
-
-
使用场景
-
既然大小和原始指针一样,那么原始指针可以用的地方,这个也可以.
-
-
总结
-
对指针的封装.
-
其他的功能都是成员函数实现.
-
成员函数则是普通函数,第一参数是对象本身而已.
-
-
-
大小
-
说明
-
前面介绍了数据采用继承的形式。
-
指针的大小是不变的,那么唯一变化的就是析构类.
-
-
析构类
-
可以是
lambda
,可调用对象,其他. -
入参类型和数据指针类型一致即可.
-
-
tuple
template<std::size_t _Idx, typename _Head> struct _Head_base<_Idx, _Head, false> { _Head _M_head_impl; };template<std::size_t _Idx, typename _Head> struct _Head_base<_Idx, _Head, true> { };template<std::size_t _Idx, typename _Head, typename... _Tail> struct _Tuple_impl<_Idx, _Head, _Tail...>: public _Tuple_impl<_Idx + 1, _Tail...>,private _Head_base<_Idx, _Head> { };
-
空类无成员变量,非空类有成员变量.
-
模板元变成.智能代码生成器.
-
-
-
实现
-
说明
-
实现了构造和移动。
-
拷贝被
delete
掉了.
-
-
分析
// Disable copy from lvalue. unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete;
-
可以看到拷贝构造和拷贝赋值都被
delete
. -
参与匹配,但是报错.
-
-
移动
void reset(pointer __p = pointer()) noexcept { using std::swap;swap(_M_t._M_ptr(), __p);if (__p != pointer())get_deleter()(__p); }pointer release() noexcept { pointer __p = get();_M_t._M_ptr() = pointer();return __p; }unique_ptr& operator=(unique_ptr&& __u) noexcept { reset(__u.release());get_deleter() = std::forward<deleter_type>(__u.get_deleter());return *this; }
-
先对
__u
执行release
,即返回并修改为空,返回值. -
在执行
reset
进行交换并释放原值(交换出来的 __p )
. -
赋值传递了数据和析构对象.
-
-
-
使用
-
工厂类
-
创建一个成员并返回.
-
-
须知
-
返回时,局部变量变成右值.
-
然后外部接收对象调用右值构造.
-
-
移动
-
移动代表着资源转移.
-
原始资源的释放.
-
-
交换
-
互换,不涉及释放.
-
-
转移失败
- 析构.
-
析构失败
signal
崩溃.abort
无unwind stack
.
-
-
析构
-
回顾
-
默认用
delete
. -
可以自定义析构.
-
-
自定义析构
- 由于采用
tuple
,数据之间采用继承的方式组合. - 所以可以减少空类占用数据.
- 由于采用
-
注意
- 默认是指针,大小固定.
- 加了自定义函数可能会增大.
-
-
拓展
-
数组
-
需要以数组的形式创建.
#include<memory> #include<iostream> class D{ public:D(){ std::cout << __FUNCTION__ << std::endl;}~D(){ std::cout << __FUNCTION__ << std::endl;} };int main() { std::unique_ptr<D[]> d(new D[5]); }
-
这里的类型是
D[]
,而不是D
.即数组和单个元素的差别. -
调用也有一些差别.
-
重载的函数也是数组的操作
[]
,不支持*,->
操作. -
通常用在
C
风格的函数返回数组.C++
一般是使用容器.
-
-
转换为
shared_ptr
-
因为是独占的,所以可以理解为共享,只是计数只能为
1
. -
同时支持独占和共享的转换也是作为工厂函数的原因之一.
-
-
详细解决方案
C++11 智能指针 unique_ptr,让资源管理更简单,更安全
热度:34 发布时间:2023-12-22 02:44:03.0
相关解决方案
- 《Oracle 基础教程》课程学习(22)——第4部分 性能调整——第22章 Oracle 资源管理
- C++基础知识 - unique_ptr 使用详解 (C++11)
- C++智能指针:unique_ptr、shared_ptr、weak_ptr
- K8s--资源管理
- C++---智能指针(auto_ptr、unique_ptr、shared_ptr)
- 第三章 资源管理
- std::unique_ptr<>
- FreeRTOS笔记篇:第七章 -- 资源管理(互斥锁、二进制信号量、死锁)
- Android 资源管理 Asset 、Raw 和Drawable
- 【effective c++读书笔记】【第3章】资源管理
- unique_ptr 源码分析
- C++11 智能指针 unique_ptr,让资源管理更简单,更安全
- 【Linux面试题】资源管理
- 从零开始学C++之对象语义与值语义、资源管理(RAII、资源所有权)、模拟实现auto_ptrclass、实现Ptr_vector
- 关于Linux中控制群组cgroup(资源管理)的一些笔记
- Spring 资源管理
- 资源管理(k8s)Resource(上)
- Hadoop -- YARN 资源管理,任务调度
- 【C++】智能指针(二)--unique_ptr、shared_ptr和wear_ptr
- 智能指针(详解)——unique_ptr
- Maven高级 聚合与继承 版本管理 资源管理 多环节开发配置 跳过测试 私服
- C++ 11 创建和使用 unique_ptr
- C++11智能指针-unique_ptr
- std::unique_ptr 独占所有权智能指针
- C++11 - std::shared_ptr和std::unique_ptr