Android 强指针和弱指针

转载 2013年12月02日 13:43:35

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

     Android的智能指针相关的源代码在下面两个文件中:

frameworks\base\include\utils\RefBase.h

frameworks\base\libs\utils\RefBase.cpp

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

 

   Android中定义了两种智能指针类型,一种是强指针spstrongpointer),一种是弱指针(weakpointer)。其实成为强引用和弱引用更合适一些。强指针与一般意义的智能指针概念相同,通过引用计数来记录有多少使用者在使用一个对象,如果所有使用者都放弃了对该对象的引用,则该对象将被自动销毁。

   弱指针也指向一个对象,但是弱指针仅仅记录该对象的地址,不能通过弱指针来访问该对象,也就是说不能通过弱指针来调用对象的成员函数或访问对象的成员变量。要想访问弱指针所指向的对象,需首先将弱指针升级为强指针(通过wp类所提供的promote()方法)。弱指针所指向的对象是有可能在其它地方被销毁的,如果对象已经被销毁,wppromote()方法将返回空指针,这样就能避免出现地址访问错的情况。

   是不是很神奇?弱指针是怎么做到这一点的呢?其实说穿了一点也不复杂,原因就在于每一个可以被智能指针引用的对象都同时被附加了另外一个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一个智能指针,即deletep_obj。不要担心对象的销毁问题,智能指针的最大作用就是自动销毁不再使用的对象。不需要再使用一个对象后,直接将指针赋值为NULL即可:

    p_obj= NULL;

   上面说的都是强指针,弱指针的定义方法和强指针类似,但是不能通过弱指针来访问对象的成员。下面是弱指针的示例:

    wp<MyClass>wp_obj = new MyClass();

    p_obj= wp_obj.promote(); // 升级为强指针。不过这里要用.而不是->,真是有负其指针之名啊

    wp_obj= NULL;

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

   

Android强指针和弱指针

基类RefBase  Android中强指针和弱指针都要继承自RefBase类。   值得注意得是,Refbase类中有内部类weakref_type,有一个类型为weakref_impl*的成员变...
  • Invoker123
  • Invoker123
  • 2017年09月03日 04:25
  • 206

Android轻量级指针 强指针 弱指针

这3种指针,在这篇博客http://blog.csdn.net/luoshengyang/article/details/6786239中讲的比较详细。我们这边自己再重新梳理,总结下。 这3种指针都是...
  • kc58236582
  • kc58236582
  • 2016年08月23日 11:08
  • 1033

ARC中强指针与弱指针

ARC是苹果为了简化程序员对内存的管理,推出的一套内存管理机制 使用ARC机制,对象的申请和释放工作会在运行时,由编译器自动在代码中添加retain和release 1> strong:强指针...
  • LiuHang03
  • LiuHang03
  • 2015年11月18日 09:53
  • 646

[Android]智能指针用法(SP强指针WP弱指针)

概念 强指针 弱指针 用法 强指针 弱指针 缺点 这两天分析问题的时候看到了 sp< xxx > wp< xxx > 这样的类型定义。查阅资料后了解到这是 Android 中智能指针的用法。概念智能指...
  • dearsq
  • dearsq
  • 2016年09月08日 10:46
  • 1348

sp<> wp<>-Android中定义了两种智能指针强指针sp和弱指针wp

Android中定义了两种智能指针类型,一种是强指针sp(strong pointer),另外一种是弱指针(weak pointer)。其实称之为强引用和弱引用更合适一些。强指针与一般意义的智能指针概...
  • liuxd3000
  • liuxd3000
  • 2016年02月02日 15:30
  • 832

Android 强弱指针分析

Android 强弱指针分析在C C++ 语言中,内存的管理历来是一个比较难的问题,在java 中内存new 的对象由jvm 虚拟机自动回收。在Android 上面提供了sp 和wp 两种类型...
  • chituhuan
  • chituhuan
  • 2016年12月02日 21:11
  • 786

Rust 指针与其对应的C样式指针

翻译来源https://github.com/diwic/reffers-rs/blob/master/docs/Pointers.md前言若你是一名C程序员,你经常用指针,在Rust中有什么替代方案...
  • guiqulaxi920
  • guiqulaxi920
  • 2017年12月19日 20:37
  • 121

强指针和弱指针

在Android的源代码中,经常会看到形如:sp、wp这样的类型定义,这其实是Android中的智能指针。智能指针是C++中的一个概念,通过基于引用计数的方法,解决对象的自动释放的问题。在C++编程中...
  • yuanfen139re
  • yuanfen139re
  • 2013年10月26日 19:08
  • 439

[转载]强指针和弱指针

[转载]强指针和弱指针2010-12-14 16:27在Android的源代码中,经常会看到形如:sp、wp这样的类型定义,这其实是Android中的智能指针。智能指针是C++中的一个概念,通过基于...
  • yuzaipiaofei
  • yuzaipiaofei
  • 2011年07月15日 09:33
  • 357

iOS开发之-指针小结

1>指针分类:    (1)强指针:默认情况下,都是强指针(__strong)    (2)弱指针: __weak 修饰  指针:指针是一个地址,我们可以通过获取地址来操控此地址中存储空间的值。 2>...
  • jiisd
  • jiisd
  • 2015年03月22日 22:59
  • 1732
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 强指针和弱指针
举报原因:
原因补充:

(最多只允许输入30个字)