文章目录
引用RefBase.h头文件
frameworks/rs/cpp/util/RefBase.h
用例1
#include <iostream>
#include <string.h>
#include <unistd.h>
#include "RefBase.h"
using namespace std;
using namespace android::RSC;
class Person : public LightRefBase<Person>
{
public:
Person(){ cout<<"new Person()"<<endl; }
~Person(){ cout<<"~ Person"<<endl; }
void print(){ cout<<"this Person"<<endl; }
};
int main()
{
sp<Person> m = new Person();
return 0;
}
运行结果:
new Person()
~ Person
用例2
#include <iostream>
#include <string.h>
#include <unistd.h>
#include "RefBase.h"
using namespace std;
using namespace android::RSC;
class Person : public LightRefBase<Person>
{
private:
sp<Person> fa;
sp<Person> so;
public:
Person(){ cout<<"new Person()"<<endl; }
~Person(){ cout<<"~ Person"<<endl; }
void print(){ cout<<"this Person"<<endl; }
void setFa(sp<Person> &fao){ this->fa=fao; }
void setSo(sp<Person> &sao){ this->so=sao; }
};
int main()
{
sp<Person> m = new Person();
sp<Person> n = new Person();
return 0;
}
结果:
new Person()
new Person()
~ Person
~ Person
分析上面的代码 new Person();时会先执行内部其他对象的构造函数,再构造本身
new sp
new sp
new Person()
接下来对比分析用例3和用例4
用例3
#include <iostream>
#include <string.h>
#include <unistd.h>
#include "RefBase.h"
using namespace std;
using namespace android::RSC;
class Person : public LightRefBase<Person>
{
private:
sp<Person> fa;
sp<Person> so;
public:
Person(){ cout<<"new Person()"<<endl; }
~Person(){ cout<<"~ Person"<<endl; }
void print(){ cout<<"this Person"<<endl; }
void setFa(sp<Person> &fao){ this->fa=fao; }// = 号操作会增加对象的引用计数
//this-> 表示本类中的成员(通用)
void setSo(sp<Person> &sao){ this->so=sao; }
};
int main()
{
sp<Person> m = new Person();
sp<Person> n = new Person();
m->setFa(n);
n->setFa(m);
return 0;
}
执行结果:
new Person()
new Person()
用例4
int main()
{
sp<Person> m = new Person();
sp<Person> n = new Person();
//m->setFa(n);
n->setFa(m);
return 0;
}
执行结果:
new Person()
new Person()
~ Person
~ Person
分析,
分析的关键点
1、在上面就提到过new Person();时会先执行内部其他对象的构造函数,再构造本身,而在析构时会相反。我们可以修改StrongPointer.h的sp类增加打印消息
2、源头是对栈进行析构,~sp —> 中判断引用计数,引用计数为0时,执行对Person类的析构。
例4的结果: -------------------------- 例3的执行结果
new sp new sp
new sp new sp
new Person() new Person()
new sp new sp
new sp new sp
new Person() new Person()
系统对栈进行回收,自动执行sp的析构 ~sp
析构n
析构person
n的
首先是sp sp功能就是回收person
~sp ~sp
m_ptr->decStrong m_ptr->decStrong
~ Person 计数为0 delete
n 的person内部
~sp
~sp 对m的person引用减1 ~sp
m_ptr->decStrong m_ptr->decStrong
析构m
~sp
m_ptr->decStrong
~ Person
~sp
~sp
分析例4
要注意:在Person的析构被执行,其内部的sp才能被析构
用例3在析构时,会先执行n对应的sp的析构函数,再判断Person引用计数,由于引用计数不为1,因此导致~person没有被调用。
同样m一样。
用例4在析构时,会先执行n对应的sp的析构函数,这里n的Person引用计数为0,那么将执行~Person的函数,这里面存在sp成员,再次执行sp的析构,此sp指向m中的person,这里再判断m中的Person引用计数-1。
执行m对应的sp的析构函数,这里m的person引用计数再次减1,执行m的person的析构。
强指针/强引用(类似例3)-- A指向B,A决定B的生死
弱指针/弱引用(类似例4)-- A指向B,A不能决定B的生死
来看看头文件
android-5.0.2/frameworks/rs/cpp/util
#ifndef RS_REF_BASE_H
#define RS_REF_BASE_H
#include <stdint.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "StrongPointer.h"
#include "TypeHelpers.h"
....
template <class T>
class LightRefBase
{
public:
inline LightRefBase() : mCount(0) { }
inline void incStrong(__attribute__((unused)) const void* id) const {
__sync_fetch_and_add(&mCount, 1);
}
inline void decStrong(__attribute__((unused)) const void* id) const {
if (__sync_fetch_and_sub(&mCount, 1) == 1) {
delete static_cast<const T*>(this);
}
}
//! DEBUGGING ONLY: Get current strong ref count.
inline int32_t getStrongCount() const {
return mCount;
}
typedef LightRefBase<T> basetype;
protected:
inline ~LightRefBase() { }
private:
friend class ReferenceMover;
inline static void moveReferences(void*, void const*, size_t,
const ReferenceConverterBase&) { }
private:
mutable volatile int32_t mCount;
};
android-5.0.2/frameworks/rs/cpp/util/StrongPointer.h
template <typename T>
class sp
{
public:
inline sp() : m_ptr(0) { }
sp(T* other);
sp(const sp<T>& other);
template<typename U> sp(U* other);
template<typename U> sp(const sp<U>& other);
~sp(); //析构执行代码见下面
// Assignment
sp& operator = (T* other);
sp& operator = (const sp<T>& other);
template<typename U> sp& operator = (const sp<U>& other);
template<typename U> sp& operator = (U* other);
//! Special optimization for use by ProcessState (and nobody else).
void force_set(T* other);
// Reset
void clear();
// Accessors
inline T& operator* () const { return *m_ptr; }
inline T* operator-> () const { return m_ptr; }
inline T* get() const { return m_ptr; }
// Operators
COMPARE(==)
COMPARE(!=)
COMPARE(>)
COMPARE(<)
COMPARE(<=)
COMPARE(>=)
private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
void set_pointer(T* ptr);
T* m_ptr;
};
template<typename T>
sp<T>::~sp()
{
if (m_ptr) m_ptr->decStrong(this);
}