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的更多相关文章

  1. 【校招面试 之 网络】第3题 HTTP请求行、请求头、请求体详解

    1.HTTP请求报文解剖 HTTP请求报文由3部分组成(请求行+请求头+请求体): 下面是一个实际的请求报文: ①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE.HEA ...

  2. 【校招面试 之 网络】第2题 TCP的可靠传输、流量控制、滑动窗口

    1.可靠传输 (1)三次握手 TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接: (1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_S ...

  3. 【校招面试 之 C/C++】第26题 C++ 智能指针(二)之 share_ptr

    1.综述 shared_ptr 是一个标准的共享所有权的智能指针, 允许多个指针指向同一个对象. 定义在 memory 文件中(非memory.h), 命名空间为 std. shared_ptr 是为 ...

  4. 【校招面试 之 C/C++】第25题 C++ 智能指针(一)之 auto_ptr

    1.智能指针背后的设计思想 我们先来看一个简单的例子: void remodel(std::string & str) { std::string * ps = new std::string ...

  5. 【校招面试 之 网络】第1题 TCP和UDP

    TCP UDP1.TCP与UDP基本区别  (1)基于连接与无连接  (2)TCP要求系统资源较多,UDP较少:   (3)UDP程序结构较简单(头只有8个字节:源端口号.目标端口号.长度.差错)   ...

  6. 剑指offer 面试27题

    面试27题: 题目:二叉树的镜像 题:操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / ...

  7. 记2016腾讯 TST 校招面试经历,电面、笔试写代码、技术面、hr面,共5轮

    (出处:http://www.cnblogs.com/linguanh/) 前序: 距离  2016 腾讯 TST 校招面试结束已经5天了,3月27日至今,目前还在等待消息.从投简历到两轮电面,再到被 ...

  8. 墙裂推荐!2020Android阿里&腾讯&百度&字节&美团校招面试汇总

    基本情况 2021届硕士生,Android开发岗 此文主要是2020年年初春招实习的面试和正式校招面试经验汇总,最终校招拿到了腾讯,百度,美团等offer 主要包括阿里4面,腾讯实习4面和校招4面,字 ...

  9. WEB前端面试选择题解答(共36题)

    第1题 ["1", "2", "3"].map(parseInt) A:["1", "2", &qu ...

随机推荐

  1. selenium Java-1 配置

      1.使用intellij新建一个maven项目,名字自定.在pom中写入selenium的依赖.其他依赖也添加到该文件中. [maven selenium依赖](http://mvnreposit ...

  2. ssh-keygen的使用方法(无密码访问)

    一.概述 1.就是为了让两个linux机器之间使用ssh不需要用户名和密码.采用了数字签名RSA或者DSA来完成这个操作 2.模型分析 假设 A (192.168.20.59)为客户机器,B(192. ...

  3. linux开机服务自启

    有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务,主要用三种方式进行这一操作: ln -s             在/etc/rc.d/rc*.d目录中建立/etc/init.d/ ...

  4. Python的collections模块中namedtuple结构使用示例

      namedtuple顾名思义,就是名字+元组的数据结构,下面就来看一下Python的collections模块中namedtuple结构使用示例 namedtuple 就是命名的 tuple,比较 ...

  5. 清理mysql binlog日志

    1.查看binlog日志 mysql> show binary logs; +------------------+------------+| Log_name         | File_ ...

  6. [Python] 拉格朗日插值

    #-*— coding:utf-8 -*- #Program 0.3 Lagrange Interpolation import matplotlib.pyplot as plt import num ...

  7. Redis安装及五种数据类型

    redis是非关系型数据库,也叫内存数据库.数据是键值对的形式,通过key查找value 安装Radis:6379 sudo apt-get update sudo apt-get install r ...

  8. Sklearn数据集与机器学习

    sklearn数据集与机器学习组成 机器学习组成:模型.策略.优化 <统计机器学习>中指出:机器学习=模型+策略+算法.其实机器学习可以表示为:Learning= Representati ...

  9. python入门-变量和简单数据类型

    1 title() 是以首字母大写的方式显示每个单词 lower() 字母小写 upper() 字母大写 2 python使用+号来合并字符串 字符串中使用制表符用\t 字符串中使用换行符\n 用rs ...

  10. leetcode933

    public class RecentCounter { Queue<int> Q; public RecentCounter() { Q = new Queue<int>() ...