【校招面试 之 C/C++】第27题 C++ 智能指针(三)之 unique_ptr
auto_ptr<string> p1(new string ("auto") ; //#1
auto_ptr<string> p2; //#2
p2 = p1; //#3
在语句#3中,p2接管string对象的所有权后,p1的所有权将被剥夺。前面说过,这是好事,可防止p1和p2的析构函数试图刪同—个对象;
但如果程序随后试图使用p1,这将是件坏事,因为p1不再指向有效的数据。
下面来看使用unique_ptr的情况:
unique_ptr<string> p3 (new string ("auto"); //#4
unique_ptr<string> p4; //#5
p4 = p3; //#6
编译器认为语句#6非法,避免了p3不再指向有效数据的问题。因此,unique_ptr比auto_ptr更安全。
但unique_ptr还有更聪明的地方。
有时候,会将一个智能指针赋给另一个并不会留下危险的悬挂指针。假设有如下函数定义:
unique_ptr<string> demo(const char * s)
{
unique_ptr<string> temp (new string (s));
return temp;
}
并假设编写了如下代码:
unique_ptr<string> ps;
ps = demo('Uniquely special");
demo()返回一个临时unique_ptr,然后ps接管了原本归返回的unique_ptr所有的对象,而返回时临时的 unique_ptr 被销毁,也就是说没有机会使用 unique_ptr 来访问无效的数据,换句话来说,这种赋值是不会出现任何问题的,即没有理由禁止这种赋值。实际上,编译器确实允许这种赋值,这正是unique_ptr更聪明的地方。
总之,当程序试图将一个 unique_ptr 赋值给另一个时,如果源 unique_ptr 是个临时右值,编译器允许这么做;如果源 unique_ptr 将存在一段时间,编译器将禁止这么做,比如:
unique_ptr<string> pu1(new string ("hello world"));
unique_ptr<string> pu2;
pu2 = pu1; // #1 not allowed
unique_ptr<string> pu3;
pu3 = unique_ptr<string>(new string ("You")); // #2 allowed
#1留下悬挂的unique_ptr(pu1),这可能导致危害。而#2不会留下悬挂的unique_ptr,因为它调用 unique_ptr 的构造函数,该构造函数创建的临时对象在其所有权让给 pu3 后就会被销毁。这种随情况而已的行为表明,unique_ptr 优于允许两种赋值的auto_ptr 。
当然,您可能确实想执行类似于#1的操作,仅当以非智能的方式使用摒弃的智能指针时(如解除引用时),这种赋值才不安全。要安全的重用这种指针,可给它赋新值。C++有一个标准库函数std::move(),让你能够将一个unique_ptr赋给另一个。下面是一个使用前述demo()函数的例子,该函数返回一个unique_ptr<string>对象:
使用move后,原来的指针仍转让所有权变成空指针,可以对其重新赋值。
unique_ptr<string> ps1, ps2;
ps1 = demo("hello");
ps2 = move(ps1);
ps1 = demo("alexia");
cout << *ps2 << *ps1 << endl;
【校招面试 之 C/C++】第27题 C++ 智能指针(三)之 unique_ptr的更多相关文章
- 【校招面试 之 网络】第3题 HTTP请求行、请求头、请求体详解
1.HTTP请求报文解剖 HTTP请求报文由3部分组成(请求行+请求头+请求体): 下面是一个实际的请求报文: ①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE.HEA ...
- 【校招面试 之 网络】第2题 TCP的可靠传输、流量控制、滑动窗口
1.可靠传输 (1)三次握手 TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接: (1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_S ...
- 【校招面试 之 C/C++】第26题 C++ 智能指针(二)之 share_ptr
1.综述 shared_ptr 是一个标准的共享所有权的智能指针, 允许多个指针指向同一个对象. 定义在 memory 文件中(非memory.h), 命名空间为 std. shared_ptr 是为 ...
- 【校招面试 之 C/C++】第25题 C++ 智能指针(一)之 auto_ptr
1.智能指针背后的设计思想 我们先来看一个简单的例子: void remodel(std::string & str) { std::string * ps = new std::string ...
- 【校招面试 之 网络】第1题 TCP和UDP
TCP UDP1.TCP与UDP基本区别 (1)基于连接与无连接 (2)TCP要求系统资源较多,UDP较少: (3)UDP程序结构较简单(头只有8个字节:源端口号.目标端口号.长度.差错) ...
- 剑指offer 面试27题
面试27题: 题目:二叉树的镜像 题:操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / ...
- 记2016腾讯 TST 校招面试经历,电面、笔试写代码、技术面、hr面,共5轮
(出处:http://www.cnblogs.com/linguanh/) 前序: 距离 2016 腾讯 TST 校招面试结束已经5天了,3月27日至今,目前还在等待消息.从投简历到两轮电面,再到被 ...
- 墙裂推荐!2020Android阿里&腾讯&百度&字节&美团校招面试汇总
基本情况 2021届硕士生,Android开发岗 此文主要是2020年年初春招实习的面试和正式校招面试经验汇总,最终校招拿到了腾讯,百度,美团等offer 主要包括阿里4面,腾讯实习4面和校招4面,字 ...
- WEB前端面试选择题解答(共36题)
第1题 ["1", "2", "3"].map(parseInt) A:["1", "2", &qu ...
随机推荐
- 廖雪峰Java1-2程序基础-7布尔运算符
布尔运算符 关系运算符:>, >=, <, <=, ==,!= 与运算 && 或运算 | 非运算 ! int n = 5; boolean t = n > ...
- [UE4]Axis Mappings轴映射和动作映射Action Mappings的区别
这里添加的映射只能在“玩家角色(Character)”的事件蓝图中使用. 从它们设置和蓝图使用界面就能看出他们的区别
- Linux命令详解-文件系统管理
1. 外部设备简介 (1.)硬盘的分类: IDE硬盘 ./dev/hda hdb,hdc… 分区后:/dev/hda1 /dev/hda2 scsi硬盘: /dev/sda sdb,sdc ...
- javascript面向对象的程序设计之Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor()用于获取给定属性的描述信息,这个描述信息是一个对象. 如果是访问器属性,则这个对象的属性有configurable,enumerabl ...
- Web API 源码剖析之全局配置
Web API 源码剖析之全局配置 Web API 均指Asp.net Web API .本节讲述的是基于Web API 系统在寄宿于IIS. 本节主要讲述Web API全局配置.它是如何优雅的实现 ...
- [jni]Getting Started
写一个java应用程序来调用C函数打印“Hello World!" 这个过程包括以下步骤: 1:创建一个申明了native方法的java类(HelloWorld.java): 2:使用jav ...
- UNDO三大作用与一致性读机制浅析
UNDO三大作用1.一致性读(consistent read)2.事务回滚(Rollback Transaction)3.实例恢复(Instance Recovery) 一致性读当会话发出一条SQL查 ...
- 国内访问Google的方法(Google学术、Google香港、Twitter等)
通过修改host文件达到访问Google等国外网址的目的 打开下面网址,里面会定期更新host文件,而且有详细的方法 https://laod.cn/hosts/2017-google-hosts.h ...
- ubuntu16.04安装python3,numpy,pandas等量化计算库
ubunt安装python3 sudo add-apt-repository ppa:fkrull/deadsnakessudo apt-get updatesudo apt-get install ...
- snmp简单识记
免费snmp探测 http://webluker.com/webtools/snmp snmp简单网络管理协议(simple network management protocol)前身时sgmp简单 ...