Item18 Use std::unique_ptr for exclusive-ownership resource management

​   在这篇文章中我主要探讨下std::unique_ptr这个智能指针,说到智能指针就需要说下它和原始指针的区别了,原始指针很灵活但是处处都是陷阱,用不好很容易出错,但是智能指针(Smart Pointer)相比于原始指针更易用,通过RAII机制和引用计数机制来管理指针指向的资源,本文谈论是就是C++11提供的智能指针中的一个std::unique_ptr,根据本文的题目可知,这是一个excluseive-ownership,也就是所有权独享的智能指针,它的所有权只能转移,不能像shared_ptr那样可以共享所有权。

​​   上面说到了std::unique_ptr的所有权问题,接下来谈论下另外一个问题就是占用内存大小的问题,std::unique_ptr相比于其它智能指针来说有一个得天独厚的优点就是占用内存小,几乎和原始指针一样,通过std::unique_ptr来执行方法的开销和通过原始指针来执行方法的开销一样。但是有一种情况会导致std::unique_ptr的大小变大,就是需要自定义删除器的时候,下面具体来分析下这种特殊情况。

int main() {
  int *p;
  std::unique_ptr<int> ps(new int(6));
  std::cout << sizeof(p) << ":" << sizeof(ps) << std::endl;
  return 0;
}
在64位系统上,上面的代码会输出8:8

​   因为std::unique_ptr几乎不需要在内部维护什么状态,所以它的大小和原始指针是一样大的,而shared_ptr因为内部需要维护引用计数,因此其大小肯定是大于原始指针的。默认情况下当unique_ptr离开作用域后会导致调用默认的删除器,删除其指向的资源。默认的删除器很简单就是直接调用delete,这几乎是不需要在内部维护这样的信息的,只有当用户自定义删除器的时候才会在内部保存自定义的删除器,因此这也导致了占用的内存变大了(无状态的函数对象和没有捕捉参数的lambda表达式不会导致内存变大)。

int main() {
  int c = 2;
  // 带参数捕捉的lambda表达式,会导致unique_ptr占用内存变大
  auto delint = [=](int *p) {
    std::cout << c << std::endl;
    delete p;
  };
  std::unique_ptr<int, decltype(delint)> p(new int(10), delint);
  // 输出16
  std::cout << sizeof(p) << std::endl;
  return 0;
}

​   最后介绍一些std::unique_ptr的杂项作为本文的结束,第一个是std::unique_ptr对数组的支持,和shared_ptr不一样的是,unique_ptr支持T[],相应的在删除的时候会自动调用delete []来删除资源。第二个是std::unique_ptr可以很轻松的转换为std::shared_ptr,可以直接隐式转换。

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值