C++ STL智能指针系列:

  • C++ 智能指针(一) std::auto_ptr
  • C++ 智能指针(二) std::unique_ptr
  • C++ 智能指针(三) std::shared_ptr
  • C++ 智能指针(四) std::weak_ptr

文章目录

  • 前言
  • std::unique_ptr
    • unique_ptr用法
      • 在容器中使用unique_ptr
      • 常用成员方法
        • 1. operator bool()方法
        • 2. swap()方法
        • 3. operator*() & operator->() & operator[]()
        • 4. get_deleter()方法
      • 自定义deleter

前言

在上篇文章中我们提到auto_ptr,并讲解了它的不足。为了弥补这些不足,C++11提出了unique_ptr来取代auto_ptr。

std::unique_ptr

unique_ptr,翻译过来就是"唯一的指针",从字面上就很好理解。它是独享被管理对象指针所有权的智能指针,也就是说两个指针不能指向同一个资源,复制或赋值都会改变资源的所有权。下面的第三行就会报错:

unique_ptr<Object> pObj1(new Object);
unique_ptr<Object> pObj2(move(pObj1));
cout<<pObj1->num;

从上面的代码我们可以看到unique_ptr不是进行拷贝构造的,而是进行移动构造的。这也是高明之处,C++为解决STL容器内的元素必需支持可复制和可赋值,没有提供拷贝构造函数,只提供了移动构造函数。这就意味着我们无法进行左值复制构造,也无法进行左值复制赋值操作,但允许临时右值赋值构造和赋值,然后问题就解决了。

此外还有unique支持数组作为元素,其析构时会自动检测出数组,并使用delete []

unique_ptr<int[]> pArrayi(new int[10]);

我们可以来看看析构的情况:

unique_ptr<Object[]> pArrayObj(new Object[10]);

输出:

Create Object
Create Object
Create Object
Create Object
Create Object
Create Object
Create Object
Create Object
Create Object
Create Object
Free Resources
Free Resources
Free Resources
Free Resources
Free Resources
Free Resources
Free Resources
Free Resources
Free Resources
Free Resources

unique_ptr用法

在容器中使用unique_ptr

刚才我们讲了为什么unique_ptr可以在STL容器中使用,现在我们来看看具体用法:

vector<unique_ptr<string>> vec;
unique_ptr<string> ps1(new string("Hello"));
unique_ptr<string> ps2(new string("World"));vec.push_back(std::move(ps1));
vec.push_back(std::move(ps2));

我们要注意赋值时必须使用std::move方法转化为右值才可赋值:

vec[0] = move(vec[1]);

常用成员方法

unique_ptr中的get()release()reset()方法与auto_ptr相同,此外,unique_ptr还提供了其他的一些函数。

1. operator bool()方法

operator bool():重载了bool,可以直接判断是否为空:

unique_ptr<Object> pObj(new Object);
pObj.reset();
if(pObj){cout<<"is not a null pointer"<<endl;
}else{cout<<"is a null pointer"<<endl;
}

2. swap()方法

swap()方法可以交换两个unique_ptr的托管对象:

class Object{public:Object(int num):num(num){}~Object(){}
public:int num;
};int main(){unique_ptr<Object> pObj1(new Object(123));unique_ptr<Object> pObj2(new Object(456));cout<<"pointer 1: "<<pObj1->num<<endl;cout<<"pointer 2: "<<pObj2->num<<endl;pObj1.swap(pObj2);cout<<"pointer 1: "<<pObj1->num<<endl;cout<<"pointer 2: "<<pObj2->num<<endl;
}

输出内容:

pointer 1: 123
pointer 2: 456
pointer 1: 456
pointer 2: 123

3. operator*() & operator->() & operator

对于单对象,使用operator*()operator->(),方法与auto_ptr一样。对于数组版本,则使用operator[]()

unique_ptr<int[]> pObj(new int[5]);
for(int i=0;i<5;i++)cout<<&pObj[i]<<endl;

输出如下:

0x2041660dc00
0x2041660dc04
0x2041660dc08
0x2041660dc0c
0x2041660dc10

4. get_deleter()方法

可以获取unique_ptr的删除器:

unique_ptr<Object> pObj(new Object());
auto del = pObj.get_deleter();

此外,unique_ptr还支持自定义删除器。

自定义deleter

我们先来看看unique_ptr源代码:

template <typename _Tp, typename _Dp = default_delete<_Tp>>
class unique_ptr
{...
};

可以看到我们还可以传入一个deleter。自定义deleter的应用场景是假如一个对象,不是通过delete释放的,那么就需要我们使用自定义的deleter。举个例子,C语言的标准文件操作使用FILE*指针作为句柄,然后使用fclose()放资源。我们想要使用unique_ptr代理,使其在离开作用域的时候自动释放:
自定义的deleter:

class FileDeleter{public:void operator()(FILE* _fp){if(_fp != nullptr){cout<<"Free resource ..."<<endl;fclose(_fp);}}
};

这里是重载了一下()运算符,使其成为一个伪函数。或者我们可以直接使用函数:

void FileDeleter(FILE* _fp){if(_fp != nullptr){cout<<"Free resource ..."<<endl;fclose(_fp);}
}

在某一函数中使用:

void scope(){unique_ptr<FILE,FileDeleter> file(fopen("test.txt","w"),FileDeleter());fputs("test",file.get());
}

如果是函数,注意传入是这样使用:

    unique_ptr<FILE,void (*)(FILE*)> file(fopen("test.txt","w"),FileDeleter);

然后调用函数:

int main(){scope();cout<<"Has left the scope"<<endl;
}

我们可以看到在退出作用域时就调用了FileDeleter

Free resource ...
Has left the scope

C++ 智能指针(二) std::unique_ptr相关推荐

  1. c++11 智能指针 (std::unique_ptr)(一)

    定义于头文件 <memory> template<class T,class Deleter = std::default_delete<T>> class uni ...

  2. c++11 智能指针 (std::unique_ptr)(六)

    定义于头文件 <memory> template< class T, class Deleter = std::default_delete<T>>class un ...

  3. C++的智能指针auto_ptr、unique_ptr源码解析

    C++的智能指针auto_ptr.unique_ptr源码解析 1.前言 2.源码准备 3.源码解析 3.1.auto_ptr解析 3.2.unique_ptr解 3.3.unique_ptr的一个偏 ...

  4. C++智能指针shared_ptr、unique_ptr以及weak_ptr

    目录 shared_ptr类 shared_ptr和unique_ptr都支持的操作 shared_ptr独有的操作 make_shared函数 shared_ptr自动销毁所管理的对象 由普通指针管 ...

  5. 智能指针shared_ptr、unique_ptr、weak_ptr

    智能指针 智能指针解决的问题 智能指针分类 shared_ptr 内存模型图 shared_ptr示例 shared_ptr含义 shared_ptr基本用法及常用函数 常用函数 智能指针的构造,初始 ...

  6. c++系列 —— 智能指针auto_ptr和unique_ptr

    往期地址: c++系列一 -- c++的封装 c++系列二 -- c++的继承 c++系列三 -- 继承和多态特性 c++系列四 -- 运算符重载 c++系列五 -- 静态成员和静态类 c++系列六 ...

  7. 智能指针(shared_ptr、unique_ptr、weak_ptr)的使用

    智能指针的使用 一.shared_ptr 1.创建一个shared_ptr 2.shared_ptr的常用成员函数 reset成员函数的使用 3.==注意事项== 二.unique_ptr 1.uni ...

  8. 深入学习c++--智能指针(二) weak_ptr(打破shared_ptr循环引用)

    1. 几种智能指针 1. auto_ptr: c++11中推荐不使用他(放弃) 2. shared_ptr: 拥有共享对象所有权语义的智能指针 3. unique_ptr: 拥有独有对象所有权语义的智 ...

  9. C++智能指针入门之unique_ptr

    智能指针解决了程序员忘记释放对象,导致内存遗漏的问题 如下: #include <iostream> #include <memory> #include <unistd ...

最新文章

  1. python查询字典里的多个key_Python:如何快速找到多个字典中的公共键(key)
  2. spring和spring_Spring交易可见性
  3. vue 横向菜单滚动定位_使用vue组件+iscroll实现一个横向菜单,不能正确滑动
  4. 【转】在树莓派上实现人脸识别
  5. CVPR2021 P2GAN:提高图像风格迁移的鲁棒性
  6. 王一博、张艺兴等多位明星起诉医美平台更美App
  7. 如何分析及处理 Flink 反压?
  8. 【RecSys】推荐系统和计算广告经典算法论文及实现总结
  9. 急救护理虚拟仿真实验室
  10. NALI显示IP地理位置
  11. 我的2011--衣带渐宽终不悔,为伊消得人憔悴
  12. js——分享QQ、QQ空间、微信、微博
  13. 图解 Redis,还有人看不懂?
  14. Win7 X64 SQL SERVER 2000企业管理器无法建立新表
  15. 我在网易云音乐里看到的那些关于考研的故事
  16. 扫地机器人自动回充原理
  17. 汉语拼音的模糊音扩展(用于搜索纠错)
  18. linux 街机列表,linux下街机模拟器联机
  19. IBDP tok课程是什么课?怎么拿高分?
  20. BadUsb----结合实例谈此类外设的风险

热门文章

  1. 【SQL】经典50题 [ 3 ]:Q31-Q50
  2. 项目管理(PMP)项目进度管理
  3. 【043】基于51单片机的篮球比赛积分计时系统Proteus仿真
  4. 微信电脑端【多开问题】+附赠,解决桌面图标变小白块问题
  5. OpenMP: sections分段并行
  6. SVN如何对已经提交的注释进行再次修改?
  7. Abaqus2019的abaqus_v6.env在哪里
  8. cannot unbox null value
  9. docker 容器运行后不退出
  10. ios 扇形 按钮_iOS 饼状图(扇形图)动画效果的实现