ANDROID -- sp,wp,RefBase 使用

来源:互联网 发布:蓝鸟编程使用教程 编辑:程序博客网 时间:2024/05/02 02:11

http://blog.chinaunix.net/uid-24922718-id-3787722.html

今天研究了下android中的智能指针,在这里记录下使用心得。
    android中的智能指针的实现比stl中autoptr或是boost中的sharedptr实现都来的复杂,主要其中加入了强计数器和弱计数器两个概念,不像以往之使用一个计数器来进行引用技术的工作。而这个关键技术的实现细节就在下面要介绍的类中。
    RefBase类:
        这个类可以说是想要用这套智能指针的葵花宝典,最主要是因为计数器的实现在其内部,所以,所有想要用智能指针来管理的对象内存空间,其对象的必定要继承自该类。主要的代码走度这里就不说了,网上多的是,主要还是记录下自己对其使用的理解。
        从例子着手:
        

点击(此处)折叠或打开

  1. class strongA : public RefBase
  2. {  
  3.         public:
  4.                 strongA(){}
  5.                 ~strongA(){
  6.                         printf("delete strong A\n");
  7.                 }
  8. };
  在这我们定义了一个strongA类,这个类这么定义之后就可以使用智能指针来管理其创建出来的内存空间了。
   通过源码,可以看到RefBase类中有一个公共接口extendObjectLifetime()。 这个接口的参数是以下这个枚举:
  

点击(此处)折叠或打开

  1. enum {
  2.         OBJECT_LIFETIME_STRONG = 0x0000,
  3.         OBJECT_LIFETIME_WEAK = 0x0001,
  4.         OBJECT_LIFETIME_MASK = 0x0001
  5.     };
    默认如果在你的类中没有指明类型的话,默认是第一个。那就说下这三个参数的含义:
   OBJECT_LIFETIME_STRONG:代表这个类的生命周期以来于强计数器(也就是说:只有在这个对象内存空间中的强计数器值为0的时候才会销毁对象)
   OBJECT_LIFETIME_WEAK:  
代表这个类的生命周期以来于弱计数器(也就是说:只有在这个对象内存空间中的强计数器和弱计数器的值均为0的时候才会销毁对象
  
OBJECT_LIFETIME_MASK:  表示不管这两个计数器是不是都为0,都不销毁对象,就是说智能指针管理这个内存的效果和一般的指针无异,还是要自己手动去del


 SP:
        sp模板类定义的就是用一个强指针去管理给定的内存空间,当将其指向一个对象后,该对象的强弱计数器都会加1,当然,当这个模板类对象离开了自己的作用域,强弱计数器也是一起减1,当强计数器的值为0后,便会销毁对象。

    

点击(此处)折叠或打开

  1. class strongA : public RefBase
  2. {
  3.         public:
  4.                 strongA(){}
  5.                 ~strongA(){
  6.                         printf("delete strong A\n");
  7.                 }
  8. };

  9. class weakA :public RefBase
  10. {
  11.         public:
  12.                 weakA()
  13.                 {
  14.                         extendObjectLifetime(OBJECT_LIFETIME_WEAK);
  15.                 }
  16.                 ~weakA(){
  17.                         printf("delete weak A\n");
  18.                 }
  19. };

  20. int main()
  21. {
  22.         strongA *m_sA = new strongA();
  23.         //wp<strongA> P_m= m_sA;
  24.         //printf("strong A's strong count %d\n",m_sA->getStrongCount());
  25.         //printf("strong A's weak count %d\n",m_sA->getWeakRefs()->getWeakCount());
  26.                                                                       
  27.                 sp<strongA> P_sA= m_sA;
  28.         {
  29.                 printf("strong A's strong count %d\n",m_sA->getStrongCount());
  30.                 printf("strong A's weak count %d\n",m_sA->getWeakRefs()->getWeakCount());
  31.         }
  32.         printf("strong A's strong count %d\n",m_sA->getStrongCount());
  33.         printf("strong A's weak count %d\n",m_sA->getWeakRefs()->getWeakCount());
  34.         return 0;
  35. }


点击(此处)折叠或打开

  1. class strongA : public RefBase
  2. {
  3.         public:
  4.                 strongA(){}
  5.                 ~strongA(){
  6.                         printf("delete strong A\n");
  7.                 }
  8. };

  9. int main()
  10. {
  11.         strongA *m_sA = new strongA();
  12.                                                                       
  13.                 sp<strongA> P_sA= m_sA;
  14.         {
  15.                 printf("strong A's strong count %d\n",m_sA->getStrongCount());
  16.                 printf("strong A's weak count %d\n",m_sA->getWeakRefs()->getWeakCount());
  17.         }
  18.         printf("strong A's strong count %d\n",m_sA->getStrongCount());
  19.         printf("strong A's weak count %d\n",m_sA->getWeakRefs()->getWeakCount());
  20.         return 0;
  21. }
运行结果:

点击(此处)折叠或打开

  1. root@android:/data #./hello
  2. strong A's strong count 1
  3. strong A's weak count 1
  4. delete strong A
  5. strong A's strong count 1074179188
  6. strong A's weak count 1074179188

可以看到,赋值sp后,强弱计数器都加了1,但是当离开区域后,就减1了,最后,当发现强计数器为0后,进行了对象的del操作

wp:
    弱指针相对于强指针的不同之处就是,弱指针不进行强计数器的加减操作,只对弱计数器加减,这样一来,就无法控制对象的销毁了,这个指针的好处就在这,当你想用一个对象,又不想对这个对象的销毁动作做什么贡献的话,就可以用弱指针,具体实际作用还是要看实际使用中的效果。

下面看下指定参数后的对象实例:

点击(此处)折叠或打开

  1. class strongA : public RefBase
  2. {
  3.         public:
  4.                 strongA(){}
  5.                 ~strongA(){
  6.                         printf("delete strong A\n");
  7.                 }
  8. };

  9. class weakA :public RefBase
  10. {
  11.         public:
  12.                 weakA()
  13.                 {
  14.                         extendObjectLifetime(OBJECT_LIFETIME_WEAK);
  15.                 }
  16.                 ~weakA(){
  17.                         printf("delete weak A\n");
  18.                 }
  19. };

  20. int main()
  21. {
  22.         weakA *m_sA = new weakA();
  23.         wp<weakA> P_m= m_sA;
  24.         //printf("strong A's strong count %d\n",m_sA->getStrongCount());
  25.         //printf("strong A's weak count %d\n",m_sA->getWeakRefs()->getWeakCount());
  26.                                                                       
  27.         {

  28.                 sp<weakA> P_sA= m_sA;
  29.                 printf("strong A's strong count %d\n",m_sA->getStrongCount());
  30.                 printf("strong A's weak count %d\n",m_sA->getWeakRefs()->getWeakCount());
  31.         }
  32.         printf("strong A's strong count %d\n",m_sA->getStrongCount());
  33.         printf("strong A's weak count %d\n",m_sA->getWeakRefs()->getWeakCount());
  34.         return 0;
  35. }

结果:

点击(此处)折叠或打开

  1. strong A's strong count 1
  2. strong A's weak count 2
  3. strong A's strong count 0
  4. strong A's weak count 1
  5. delete weak A

可以发现当强计数器为0了也没有析构对象,只有当两个都为0了才析构。

大致的使用就这样了,具体的还要等日后使用多了对其再深入了解!

0 0
原创粉丝点击