码迷,mamicode.com
首页 > 编程语言 > 详细

【校招面试 之 C/C++】第27题 C++ 智能指针(三)之 unique_ptr

时间:2018-07-22 17:41:56      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:方式   ack   col   ret   标准库   代码   cout   class   重用   

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

标签:方式   ack   col   ret   标准库   代码   cout   class   重用   

原文地址:https://www.cnblogs.com/xuelisheng/p/9350765.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!