智能指针

本文介绍了智能指针的概念,包括指针问题的来源及如何设计智能指针。详细讲解了强指针sp和弱指针wp的实现原理,涉及引用计数、生命周期管理,并探讨了它们在解决循环引用问题中的作用。同时,讨论了RefBase类及其在智能指针管理中的重要角色。
摘要由CSDN通过智能技术生成

智能指针

总体描述

1.简介

1.指针问题的常见来源

  • 指针没有初始化
  • new了对象后没有及时delete,导致内存泄漏。
  • 野指针;使用delete后的对象,会导致系统崩溃。

通过delete释放了对象,但没有将指针置空。

2.如何设计一个智能指针

考虑的因素:

  1. 初始化;
  2. 实现new和delete的配套;

具体的设计实现:

我们将智能指针称为SmartPointer。

  • SmartPointer是一个类

首先想到的是,SmartPointer要能记录内存对象Object的地址,它的内部应该有一个变量指向Object,所以SmartPointer是一个类。

class SmartPointer{
    private:
        void* m_ptr;//指向Object对象
}
  • SmartPointer是一个模板类

智能指针并不是针对某种特定类型的对象而设计的,因而一定是模板类。

template <typename T> class SmartPointer{
    private:
        T* m_ptr;//指向Object对象
}
  • SmartPointer的构造函数

智能指针需要考虑的一个问题就是初始化,所以智能指针的构造函数应将m_ptr置空。

template <typename T> class SmartPointer{
    inline SmartPointer() : m_ptr(0) {}
    private:
        T *m_ptr;//指向Object
}
  • 引用计数

智能指针还需考虑的一个问题是什么时候释放一个内存对象?可以考虑通过引用计数来统计对象使用的次数,如果对象的引用次数为0了,则可以释放该对象了。引用计数该由谁来管理呢?

如果由智能指针自己来维护引用计数的话,将会出现引用计数不一致的情况,导致致命错误。

如果由引用对象Object自己维护计数器,则可以解决此问题。我们可以定义一个统一的具备计数功能的父类Object。

template <class T> class LightRefBase{
    public:
        inline LightRefBase() : mCount(0) {}
        // 增加引用计数
        inline void incStrong() const {
            android_atomic_inc(&mCount);
        }
        // 减小引用计数
        inline void decStrong() const {
            if(android_atomic_dec(&mCount) == 1){
                delete static_cast<const T*>(this);//删除内存对象
            }
        }
    protected:
        inline ~LightBaseRef() {}
    private:
        muteable volatile int32_t mCount;//引用计数值
}

为此智能指针SmartPointer需要重载“=”运算符,其定义也需要修改:

template <typename T> class SmartPointer{
    inline SmartPointer() : m_ptr(0) {}
    ~SmartPointer();
    SmartPointer& operator = (T* other);//重载运算符

    private:
        T* m_ptr;
}

template <typename T> SmartPointer<T>& SmartPointer<T>::operator = (T *other){
    if(other != null){
        other->incStrong();//主动增加计数值
    }
    if(m_ptr){
        m_ptr->decStrong();// 避免重复赋值的情况
    }
    m_ptr = other;//指向内存对象Object
    return *this;
}

template <typename T> SmartPointer<T>::~SmartPointer(){
    if(m_ptr){
        m_ptr->decStrong();
    }
}

普通引用计数将可能出现循环引用的情况,为此需要采用另外一种引用计数技术,即对象的引用计数同时存在强引用计数和弱引用计数两种。它们遵循这样的规则:

  • 只要对象的强引用计数为0,不管它的弱引用计数是否为0,都可以回收该对象;
  • 弱指针必须先升级为强指针,才能访问它所指向的目标对象;如果使用一个只持有弱引用计数的对象,则需要先把这个弱引用对象升级为强引用,才能使用该对象。如果升级失败,则说明该对象已经不存在了,不能再使用了。

3.智能指针分类

根据引用计数器类以及智能指针对象类,可以将智能指针分为三大类:

  • 轻量级指针(Light Pointer)
    • 引用计数类为LightRefBase类;
    • 智能指针对象类为sp类;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值