C++ 智能指针-使用系统头文件(轻量级)

引用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);
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值