在Android的源代码中,经常会看到形如:sp<xxx>、wp<xxx>这样的类型定义,这其实是Android中的智能 指针。智能指针是C++中的一个概念,通过基于引用计数的方法,解决对象的自动释放的问题。在C++编程中,有两个很让人头痛的问题:一是忘记释放动态申 请的对象从而造成内存泄露;二是对象在一个地方释放后,又在别的地方被使用,从而引起内存访问错误。程序员往往需要花费很大精力进行精心设计,以避免这些 问题的出现。在使用智能指针后,动态申请的内存将会被自动释放(有点类似Java的垃圾回收),不需要再使用delete来释放对象,也不需要考虑一个对 象是否已经在其它地方被释放了,从而使程序编写工作减轻不少,而程序的稳定性大大提高。  

Android的智能指针相关的源代码在下面两个文件中:
  frameworks/base/include/utils/RefBase.h
  frameworks/base/libs/utils/RefBase.cpp
  

涉及的类以及类之间的关系如下图所示:

  Android中定义了两种智能指针类型,一种是强指针sp(strong pointer),一种是弱指针(weak pointer)。其实称为强引用和弱引用更合适一些。强指针与一般意义的智能指针概念相同,通过引用计数来记录有多少使用者在使用一个对象,如果所有使 用者都放弃了对该对象的引用,则该对象将被自动销毁。
  弱指针也指向一个对象,但是弱指针仅仅记录该对象的地址,不能通过弱指针来访问该对象,也就是说不能通过弱智真来调用对象的成员函数或访问对象的成员 变 量。要想访问弱指针所指向的对象,需首先将弱指针升级为强指针(通过wp类所提供的promote()方法)。弱指针所指向的对象是有可能在其它地方被销 毁的,如果对象已经被销毁,wp的promote()方法将返回空指针,这样就能避免出现地址访问错的情况。
  是不是很神奇?弱指针是怎么做到这一点的呢?其实说穿了一点也不复杂,原因就在于每一个可以被智能指针引用的对象都同时被附加了另外一个 weakref_impl类型的对象,这个对象中负责记录对象的强指针引用计数和弱指针引用计数。这个对象是智能指针的实现内部使用的,智能指针的使用者 看不到这个对象。弱指针操作的就是这个对象,只有当强引用计数和弱引用计数都为0时,这个对象才会被销毁。

  说了这么多原理,下面该看看到底智能指针该怎么使用了。假设现在有一个类MyClass,如果要使用智能指针来引用这个类的对象,那么这个类需满足下列两个前提条件:
  (1) 这个类是基类RefBase的子类或间接子类;
  (2) 这个类必须定义虚构造函数,即它的构造函数需要这样定义:
  virtual ~MyClass();
  满足了上述条件的类就可以定义智能指针了,定义方法和普通指针类似。比如普通指针是这样定义:
  MyClass* p_obj;
  智能指针是这样定义:
  sp<MyClass> p_obj;
  注意不要定义成 sp<MyClass>* p_obj。初学者容易犯这种错误,这样实际上相当于定义了一个指针的指针。尽管在语法上没有问题,但是最好永远不要使用这样的定义。
  定义了一个智能指针的变量,就可以象普通指针那样使用它,包括赋值、访问对象成员、作为函数的返回值、作为函数的参数等。比如:
  p_obj = new MyClass(); // 注意不要写成 p_obj = new sp<MyClass>
  sp<MyClass> p_obj2 = p_obj;
  p_obj->func();
  p_obj = create_obj();
  some_func(p_obj);
  注意不要试图delete一个智能指针,即 delete p_obj。不要担心对象的销毁问题,智能指针的最大作用就是自动销毁不再使用的对象。不需要再使用一个对象后,直接将指针赋值为NULL即可:
  p_obj = NULL;
  上面说的都是强指针,弱指针的定义方法和强指针类似,但是不能通过弱指针来访问对象的成员。下面是弱指针的示例:
  wp<MyClass> wp_obj = new MyClass();
  p_obj = wp_obj.promote(); // 升级为强指针。不过这里要用.而不是->,真是有负其指针之名啊
  wp_obj = NULL;

  智能指针用起来是很方便,在一般情况下最好使用智能指针来代替普通指针。但是需要知道一个智能指针其实是一个对象,而不是一个真正的指针,因此其运行效率是远远比不上普通指针的。所以在对运行效率敏感的地方,最好还是不要使用智能指针为好。

android refbase类的更多相关文章

  1. android Activity类中的finish()、onDestory()和System.exit(0) 三者的区别

    android Activity类中的finish().onDestory()和System.exit(0) 三者的区别 Activity.finish() Call this when your a ...

  2. Android图像格式类及图像转换方法

    Android图像格式类及图像转换方法介绍 一款软件的开发和图像密切相关,特别是移动应用程序,在视觉效果等方面是至关重要的,因为这直接关系到用户的体验效果.在Android程序开发的过程中,了解存在哪 ...

  3. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建   目录(?)[+] 什么是服务 服务有 ...

  4. 项目源码--Android答题类游戏源码

    下载源码 技术要点: 1. 精致的答题UI 2. Android的Http通信技术 3. Android数据库QLITE与其他数据存储技术 4. Android在线音乐背景技术 5. Android答 ...

  5. android application类的用法

    android application类的用法 Application是android系统Framework提供的一个组件,它是单例模式(singleton),即每个应用只有一个实例,用来存储系统的一 ...

  6. Android Matrix类以及ColorMatri

    引自:http://www.chinabaike.com/t/37396/2014/0624/2556217.html Android Matrix类以及ColorMatrix类详解 最近在系统学习了 ...

  7. android资讯类软件框架《IT蓝豹》

    android资讯类软件框架 android资讯类软件框架,支持侧滑,并且首页viewpager切换tab,tab滑动到最右侧的时候提示滑动结束, 滑动到最左侧的时候切换滑动侧滑menu.左滑和侧滑处 ...

  8. android RefBase、sp、wp

    首先RefBase在android的c++部分是作为一个所有类的基类,其作用跟Java中的Object类似 这个类中存在一个私有成员: weakref_impl* const mRefs;(weakr ...

  9. [Android Pro] 常用的android工具类和库

    reference to  : http://blog.csdn.net/lovexieyuan520/article/details/50614086 这篇博客主要记录我认为比较有用的Android ...

随机推荐

  1. KextWizard 的使用方法;以及Kext安装的几种工具下载

    a.将你需要安装的Kext拖到非中文的路径中: b.运行该软件,将Kext拖入下图对应的方框里,然后选择位置安装: c.选择修复权限和重建缓存(一个是修复Extra文件夹,一个是修复SLE) Kext ...

  2. 【原创】用Pwnage + Redsnow 制作完美越狱固件

    原帖我发表在威锋论坛 现在貌似IOS 7.X系 大行其道,就算不是IOS7.X ,很多人也装着IOS 6.X系. 进入正文前首先介绍一下自己目前的"环境" 设备:iphone4 G ...

  3. Mac配置JAVA_HOME

    首先打开终端,输入/usr/libexec/java_home,看到 /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home 说 ...

  4. C#图解教程读书笔记(第15章 委托)

    委托是C#的一个很重要的知识点. 1.什么是委托 委托在我认为,就是一系列格式相同的方法列表,可能就是定义的名称不一致,参数.返回值等都是一样的. 2.如何声明委托 delegate void MyF ...

  5. VS2010编译器下针对C#和C++的opencv的配置方法

    我们大家都知道opencv是针对C.C++编写的,没有独立的编译调试工具.所以今天就捣鼓了一下在xp vs2010下配置C++和C#环境下的opencv.请大家一步一步的按步骤操作.本人亲自鉴定可行. ...

  6. JS、jqueryie6浏览器下使用js无法提交表单的解决办法

    -----------------------JS.jqueryie6浏览器下使用js无法提交表单的解决办法---------------------------------------------- ...

  7. EasyUI Accordion下的Panel面板初始化时全部折叠

    EasyUI Accordion下的Panel面板有一个属性:selected,默认值为:false.初始化时,若设置'selected:true',则面板默认打开,效果如下: <div tit ...

  8. JdkDynamicAopProxy源码

     JdkDynamicAopProxy是通过接口实现动态代理类,主要方法是getProxy(ClassLoader classLoader), 代理类生成之后再调用目标方法时就会调用invoke方法. ...

  9. vtk读取文件中点坐标[转]

    vtk基础编程(2)-读取数据文件中的坐标点 1. 案例说明 在实际计算中,常常需要大量的数据, 这个时候数据文件就必不可少, 例如 数据文件points.dat, 中存放了三个点的坐标, 0.0 0 ...

  10. 网络虚拟化技术 TUN/TAP MACVLAN MACVTAP

    TUN 设备 TUN 设备是一种虚拟网络设备,通过此设备,程序可以方便得模拟网络行为.先来看看物理设备是如何工作的: