C++基础知识-之强指针(韦东山视频学习)

类关系

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对象本身  
         * /

1

SP <person> father= new Person();
会导致析构函数执行

template<typename T>                                                               
sp<T>::sp(T* other)                                                                
: m_ptr(other)                                                                     
  {                                                                                
    if (other) other->incStrong(this);                                                                                                                                      
  }    

2

        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;                                                                  
}   


5
析构函数如下:

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.就是强引用。

在这里插入图片描述

发布了115 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chengbeng1745/article/details/104053370