是怎么一回事?
wp其实是弱指针的意思,wp类型不能直接对类型T进行操作,要想对T进行某种操作,必需把wp升级为sp指针,使用promote()来实现升级:
wpweakp= new T();
spt = weakp.promote();
wp可能会在弱引用计数不为0的情况下被销毁,执行如下代码:
classWPTest :publicRefBase {
public:
WPTest(){
LOGD("WPTest constructor");
}
virtual~WPTest() {
LOGD("WPTest destructor");
}
virtualvoidonFirstRef() {
LOGD("first weak ptr ref callback");
}
virtualvoidonLastStrongRef(constvoid* id) {
LOGD("last strong ptr ref callback");
}
virtualvoidonLastWeakRef(constvoid* id) {
LOGD("last weak ptr ref callback");
}
};
intmain()
{
WPTest *T = newWPTest();
{
wpweakp(T);
{
LOGD("promote to strong ptr.../n");
spstrongp = weakp.promote();
LOGD("strong ptr's lifetime is just about to finish .../n");
}
LOGD("weak ptr's lifetime is just about to finish .../n");
}
LOGD("weak ptr is out of scope./n");
return0;
}
程序打印的结果是:
D/sp-wp-sample( 225): WPTest constructor
D/sp-wp-sample( 225): promote to strong ptr...
D/sp-wp-sample( 225): first weak ptr ref callback
D/sp-wp-sample( 225): strong ptr's lifetime is just about to finish ...
D/sp-wp-sample( 225): last strong ptr ref callback
D/sp-wp-sample( 225): WPTest destructor
D/sp-wp-sample( 225): weak ptr's lifetime is just about to finish ...
D/sp-wp-sample( 225): weak ptr is out of scope.
由此可见虽然wp的生命周期还没有结束,但是因为升级为sp后,sp的强引用计数为0,导致WPTest 被销毁,当强引用为0而弱引用不为0时,WPTest 销毁时,基类RefBase的mRefs指向的weakref_impl类并没有释放,从而保证了弱引用可以继续起作用,这点可以从RefBase的析构函数中看出来:
RefBase::~RefBase()
{
// LOGV("Destroying RefBase %p (refs %p)/n", this, mRefs);
if(mRefs->mWeak == 0) {
// LOGV("Freeing refs %p of old RefBase %p/n", mRefs, this);
delete mRefs;
}
}
不过也可以改变这一行为,我们修改一下WPTest的构造函数:
WPTest(){
LOGD("WPTest constructor");
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
}
这时的打印结果是:
D/sp-wp-sample( 217): WPTest constructor
D/sp-wp-sample( 217): promote to strong ptr...
D/sp-wp-sample( 217): first weak ptr ref callbac
D/sp-wp-sample( 217): strong ptr's lifetime is j
D/sp-wp-sample( 217): last strong ptr ref callba
D/sp-wp-sample( 217): weak ptr's lifetime is j
D/sp-wp-sample( 217): last weak ptr ref callback
D/sp-wp-sample( 217): WPTest destructor
D/sp-wp-sample( 217): weak ptr is out of scope.
可以看出现在只有当强引用和弱引用的计数都为0时,WPTest对象才会被销毁。