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.
和我们的分析是一致的。