智能指针

智能指针

总体描述

1.简介

1.指针问题的常见来源

  • 指针没有初始化
  • new了对象后没有及时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();
    }
}

2.强指针sp

sp是StrongPointer的简写,StrongPointer定义在frameworks/native/include/utils/StrongPointer.h

sp类的定义如下:

template <typename T>
class sp
{
public:
inline sp() : m_ptr(0) { }

sp(T* other);
sp(const sp<T>& other);
.......其他构造函数
~sp();// 析构函数


//重载运算符
sp& operator = (T* other);
sp& operator = (const sp<T>& other);
.....
void force_set(T* other);

void clear();
// 重载访问符
inline  T&      operator* () const  { return *m_ptr; }
inline  T*      operator-> () const { return m_ptr;  }
inline  T*      get() const         { return m_ptr; }

private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
void set_pointer(T* ptr);
T* m_ptr
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值