类关系
1.1 对象引用计数
LightRefBase类: 用于对象引用计数。
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;
};
1.2 Person类
继承于LightRefBase,有了person属性,有sp类的father和son两个成员。
class Person : public LightRefBase<Person>{
private:
sp<Person> father;
sp<Person> son;
public:
Person() {
cout <<"Pserson()"<<endl;
}
~Person()
{
cout << "~Person()"<<endl;
}
void setFather(sp<Person> &father)
{
this->father = father;
}
void setSon(sp<Person> &son)
{
this->son = son;
}
....
}
sp类
sp类包含person类的m_ptr (T=person)
template <typename T>
class sp
{
public:
inline sp() : m_ptr(0) { }
private:
...........
T* m_ptr;
}
图解
sp <person> father = new Person();
/* 1. 对于 new Person()
* 1.1 Person对象里的father先被构造
* 1.2 Person对象里的son被构造
* 1.3 Person对象本身
* /
SP <person> father= new Person();
会导致析构函数执行
template<typename T>
sp<T>::sp(T* other)
: m_ptr(other)
{
if (other) other->incStrong(this);
}
void setSon(sp<Person> &son)
{
this->son = son;
}
运算符=,被重载
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);
....
}
template<typename T>
sp<T>::sp(T* other)
: m_ptr(other)
{
if (other) other->incStrong(this);
}
对于运算符,右值是传的参数,左值是返回值。
sp<Person> son = new Person();
father->setSon(son);
//fathter->被重载后,就是father中m_ptr,示意图中的person类对象p1
void setSon(sp<Person> &son)
{
this->son = son;
//this指的是p1->son
//因为p1->son是sp类,sp类的"="被重载
//“=”的右值是son,左值是p1->son
}
template<typename T>
sp<T>& sp<T>::operator = (const sp<T>& other) {
// other = son
cout<<"tom operator= 1"<<endl;
// 用son.m_ptr构造 otherPtr就是指向p2person类对象叫p1
T* otherPtr(other.m_ptr);
if (otherPtr)
{
//otherPtr不为空,则p2变量的mCount值为2
otherPtr->incStrong(this);
}
// this是p1->son,因为p1->son中的m_ptr是空的。
if (m_ptr)
{
m_ptr->decStrong(this);
}
//p1->son.m_ptr = p2
m_ptr = otherPtr;
return *this;
}
析构函数如下:
template<typename T>
sp<T>::~sp()
{
if (m_ptr) m_ptr->decStrong(this);
}
所以在test_func函数中,在father对象,执行析构,则会减少对应的p1对象mCount,mCount=1; 无法释放。
同理,销毁son对象,执行析构,会减少对应的p2对象中的mCount,则mCount=1,无法释放。
原因:
在设置father的person对象p1中的son指向p2,把p2的引用值加1.就是强引用。