大型项目开发:谨慎使用智能指针-阿里云开发者社区

开发者社区> horky> 正文

大型项目开发:谨慎使用智能指针

简介: 智能指针使用上的问题 智能指针的使用太普遍了,它让程序员摆脱了内存管理的恶梦,但实际上智能指针本身也可能引入另一个恶梦。
+关注继续查看

智能指针使用上的问题

智能指针的使用太普遍了,它让程序员摆脱了内存管理的恶梦,但实际上智能指针本身也可能引入另一个恶梦。主要包括两个问题点:

  1. 性能问题。因为需要引入一些变量(bookkeeping),甚至在多线程下的一些互斥操作,它所带来的性能开销往往比想像的要高。比如以智能指针作为函数参数以及返回值时。
  2. 对象释放的时机不明确。比如std::auto_ptr,总让人感觉不明不白。而有时一些循环引用,又会导致内存泄露。

所以即便有了智能指针,程序员还是要认真考虑使用它们的时机。

智能指针的本质是所有权管理

所有权(Ownership)是一个用来管理动态分配内存的记录(bookkeeping)技术。动态分配内存的所有者需要负责在所分配内存不再需要时释放它。共享所有权时,最后一个owner负责清理。即使不是共享,也可以在代码间传递Ownership。

运用智能指针的核心是保持所有权(Ownership)的明确、清晰。一般情况下是保证所有权的单一,无论是使用WeakPtr, Scoped Pointer都可以保持所有权的单一,这时所有权可以在不同的对象/代码段转移。另一种情况就是需要共享所有权,比较常用的引用指数智能指针,就是帮助完成共享所有权的。

概括起来三个要点:

1.局部化
推荐保持单一、固定的所有权。当所有权需要在不同代码段间传递时,就要使用智能指针。
2.明确的清理时机
使用引用计数,和std::auto_ptr都会引发对释放时机的疑问。有可能引入一些隐晦的Bug。当需要共享所有权时,一定要先思考这个设计的必要性,以及内存释放的时机是否明确、清晰。
3.最好的方式不要使用指针。可以使用引用来代替指针。见后面WebKit的故事。

大型项目中的应用

Google Coding Style的约定

如果需要动态分配内存,尽量由分配的代码来持有所有权。
如果另一段代码需要访问对象,先考虑传递对象拷贝,指针或者引用,而不是传递所有权。如果确有需要时,建议使用std::unique_ptr来显示的传递所有权(使用std::move())。
除非有好的理由,否则不要共享所有权。比如为了避免复制。这时需要确定有明显的性能收益,而且所持有的对象最好是只读的, 同时建议使用std::shared_ptr:

std::shared_ptr<const Foo>;

新代码里不要再使用scoped_ptr,更不要使用std::auto_ptr, 而是使用std::unique_ptr来代替。

WebKit的故事

WebKit文档记录了他们使用引用计数指针的故事,详情见:RefPtr Basics。大意为:
早在2005年时为了解决内存泄露问题,开始使用基于引用计数的智能指针,但是它有性能问题,特别是当作函数参数和返回值传递时。后来使用C++11提供move语义(即转移所有权的方式)来解决了这个问题。(另外shared_ptr const & 的形式也可以避免不必要的引用计数操作。)

而到了2013年,WebKit的开发者发现泛滥的判空和有效性检查,于是开始倾向于尽可能地使用引用(注意:不是引用计数指针), 而不是指针。

小结

解决内存问题的最佳的途径仍然是由程序员管理好对象的生命周期。使用智能指针也是有成本的,同时也会引入一些新问题,所以需要遵循一些约定来使用。Google Chromium/Webkit都有相应用的定义:

另外明确约定一个函数是否会返回空指针,特别是对于API来说,也会帮助使用者避免一些不必要的判空处理和一些隐晦的Bug。

进一步学习:

  1. unique_ptr使用简介
  2. Reference counting smart pointers are for retards.

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《圣殿祭司的ASP.NET4.0专家技术手册》---- 1-14 项目同时使用C# 与VB语言及多组件的技巧
早期VS.NET 2002及VS.NET 2003的Visual Studio工具不支持多个组件文件(Assembly),也就是项目编译后只会产生一个dll组件,而一个组件只允许包含一种语言(因为系统会调用对应C#或VB编译程序进行编译),因此在同一个项目中要使用两种语言是办不到的;但在VS 2010中,因为项目支持多个组件,所以利用这个特性就可以同时使用两种以上的语言(如C#与VB),因此.cs或.vb的类别在项目中就可以直接拿来使用,直接就可以new instance,不需要先编译成dll文件再加以引用。
1418 0
vs 2008中使用Asp.net Ajax智能感知Intellisense
使用方法很简单 1.在Aspx文件中加入ScriptManager,即此文件可以智能感知 2.HTML中也可以,不过要注意路径,还有就是别用绝对路径 3.JS文件中加入 /// 注意路径如果不能确定的话可以直接从解决方案管理器中把MicrosoftAjax.
726 0
智能指针shared_ptr【无锁设计基于GCC】
1. shared_ptr 介绍   使用过Boost的话对shared_ptr一定有很深的印象。多个shared_ptr指向同一个对象,每个shared_ptr会使对象的引用计数加+1,当引用计数为0时, 对象将被析构。
627 0
C++面试题(四)——智能指针的原理和实现
C++面试题(一)、(二)和(三)都搞定的话,恭喜你来到这里,这基本就是c++面试题的最后一波了。      1,你知道智能指针吗?智能指针的原理。
3304 0
智能指针学习笔记
1. 介绍 本文介绍智能指针的使用。智能指针是c++ 中管理资源的一种方式,用智能指针管理资源,不必担心资源泄露,将c++ 程序员 从指针和内存管理中解脱出来,再者,这也是c++发展的趋势(这话不是我说的,见《Effective c++》和《c++实践编程》),应该认真学习一下。
904 0
开发函数计算的正确姿势 —— 使用 Fun Init 初始化项目
首先介绍下在本文出现的几个比较重要的概念: __函数计算(Function Compute)__: 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。
4429 0
C++智能指针(auto_ptr)详解
智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限。本文总结的8个问题足以涵盖auto_ptr的大部分内容。
757 0
+关注
horky
Web及移动开发技术
294
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载