android wp指针使用方法,android中 弱指针 (wp)的作用

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

前一篇文章已经分析了强指针弱指针的实现原理。我们可以知道,android中的智能指针是通过引用计数的方式方式来实现内存自动回收的。在很多情况下我们使用强指针sp就好了,那么弱指针wp的存在意义有是什么呢?wp 弱指针 在什么样的情况下才会使用呢?为了直观地了解wp存在的意义,我们先分析下面的代码。#include

#include

using namespace android;

class LightClassTwo;

class LightClassOne : public RefBase {

public:

LightClassOne() {

printf("Construct LightClassOne Object.n");

}

virtual ~LightClassOne() {

printf("Destory LightClassOne Object.n");

}

void (sp two){ mTwo = two; }

private:

sp mTwo;

};

class LightClassTwo : public RefBase {

public:

LightClassTwo() {

printf("Construct LightClassTwo Object.n");

}

virtual ~LightClassTwo() {

printf("Destory LightClassTwo Object.n");

}

void setOne(sp one){ mOne = one; }

private:

sp mOne;

};

int main(int argc, char** argv){

LightClassOne* one = new LightClassOne();

LightClassTwo* two = new LightClassTwo();

printf("LightClassOne Light Ref Count: %d.n", one->getStrongCount());

printf("LightClassTwo Light Ref Count: %d.n", two->getStrongCount());

{

sp two_sp = two;

sp one_sp = one;

printf("LightClassOne Light Ref Count: %d.n", one_sp->getStrongCount());

printf("LightClassTwo Light Ref Count: %d.n", two_sp->getStrongCount());

two->setOne(one);

one->setTwo(two);

printf("LightClassOne Light Ref Count: %d.n", one_sp->getStrongCount());

printf("LightClassTwo Light Ref Count: %d.n", two_sp->getStrongCount());

}

printf("LightClassOne Light Ref Count: %d.n", one->getStrongCount());

printf("LightClassTwo Light Ref Count: %d.n", two->getStrongCount());

return 0;

}

代码不复杂,代码中定义了两个类LightClassOne和LightClassTwo,他们都继承于RefBase,于是他们都具备了引用计数的能力。两个类除了构造析构函数外,还分别定义了对方类型的智能指针变量和相关的setXXX()函数。注意LightClassTwo中mOne对象现在是sp类型的。下面分析一下main函数的输出。

1.分别new出LightClassOne和LightClassTwo两个对象,此时构造函数调用,目前还没有任何智能指针指向这两个对象,因此强引用计数器的数值是初始值。

2.大括号里,分别构造两个sp指针指向这两个对象,强引用计数器加一,又是第一次有sp指向这两个对象,因此此时他们的强弱引用计数器是1。

3.分别互相调用setXXX()函数,在函数里面又有sp指向对象,强弱引用计数器继续增加,此时他们的强弱引用计数器是2。

4.跳出大括号时,最开始定义的两个sp(tow_sp/one_sp)对象要析构,所以他们所指对象的强弱引用计数器减1。

5.由于两个对象的强引用计数器都是1,他们互相持有对方,构成死锁,无法析构,直至程序跳出main函数结束。上述代码输出如下:Construct LightClassOne Object.

Construct LightClassTwo Object.

LightClassOne Light Ref Count: 268435456.

LightClassTwo Light Ref Count: 268435456.

LightClassOne Light Ref Count: 1.

LightClassTwo Light Ref Count: 1.

LightClassOne Light Ref Count: 2.

LightClassTwo Light Ref Count: 2.

LightClassOne Light Ref Count: 1.

LightClassTwo Light Ref Count: 1.

因此,如果两个对象互相持有对方的强指针,就可能产生死锁,内存对象无法回收,造成内存泄漏。

为了解决这个问题,我们只需要将LightClassTwo中的mOne对象改为wp类型的即可。下面继续分析main函数的输出。

1.2步骤同上,不在赘述

3.分别互相调用setXXX()函数,LightClassOne持有的是LightClassTwo的强指针,因此对象two的强弱引用计数变为2,LightClassTwo持有的是LightClassOne的弱指针,因此对象one的强引用计数不变还是1,弱引用计数变为2。

4.跳出大括号时,最开始定义的两个sp(tow_sp/one_sp)对象要析构,所以他们所指对象的强弱引用计数器减1。此时two的强弱引用计数变为1。此时one的强引用计数为0,弱引用计数变为1。默认情况下,对象的生命周期受强引用计数控制,因此对象one开始析构。

5.随着对象one的析构,one持有的成员变量mTwo也要析构,因此two对象的强弱引用计数器减到0,two对象本身也要销毁了,析构函数调用。

6.此时最后两个printf函数打印出来的数值是随机值,因为one two都是野指针了。上述代码输出如下:Construct LightClassOne Object.

Construct LightClassTwo Object.

LightClassOne Light Ref Count: 268435456.

LightClassTwo Light Ref Count: 268435456.

LightClassOne Light Ref Count: 1.

LightClassTwo Light Ref Count: 1.

LightClassOne Light Ref Count: 1.

LightClassTwo Light Ref Count: 2.

Destory LightClassOne Object.

Destory LightClassTwo Object.

LightClassOne Light Ref Count: 1075955252.

LightClassTwo Light Ref Count: 1103936560.

和我们的分析是一致的。

你可能感兴趣的:(android,wp指针使用方法)