Android中的智能指针

Android中的智能指针C/C++项目中常见的指针问题有三类:指针没有初始化,或者新申请的内存块没有按照情况进行初始化。new/delete操作符没有匹配使用,忘记delete造成内存泄漏。野指针。一个对象不知道有多少个指针引用它,当对象被在错误的时机销毁时,引用它的指针就变成了野指针。为了解决上面三个问题,智能指针被发明了出来。智能指针,简单来说就是通过引用计数法记录一个对象被...
摘要由CSDN通过智能技术生成

Android中的智能指针

C/C++项目中常见的指针问题有三类:

  1. 指针没有初始化,或者新申请的内存块没有按照情况进行初始化。
  2. new/delete操作符没有匹配使用,忘记delete造成内存泄漏。
  3. 野指针。一个对象不知道有多少个指针引用它,当对象被在错误的时机销毁时,引用它的指针就变成了野指针。

为了解决上面三个问题,智能指针被发明了出来。
智能指针,简单来说就是通过引用计数法记录一个对象被引用的次数,当引用次数变为0时自动销毁该对象,而不需要程序员手动delete。
了解引用计数法的同学,应该知道相对于可达性分析法有一个循环引用(A引用B,B引用A)的弊端,循环引用则导致了某些对象的引用次数一直不为0,从而引起内存泄漏。为了解决这个问题,C/C++添加了弱引用的概念。

下面我们逐步分析智能指针的实现原理。

自动初始化和销毁

假设定义了一个学生类:

class Student {
    public:
        Student() {
            printf("new Student");
        }
}

我们在使用这个类时,需要先new一个实例出来,使用结束后再手动delete。

Student stu = new Student();
...
//一些逻辑处理
...

//这里是否可以安全销毁stu实例?
delete stu;

上面这段代码的关键在于:经过复杂的逻辑处理后,stu实例可能被其他指针引用,导致最后无法确定是否可以安全的销毁原始指针stu。

下面通过智能指针类使用该类:

//仍然创建一个新实例
Student stu = new Student();
//以stu初始化一个sp(StrongPoint)实例
sp<Student> stuSp = new sp(stu);
...
//一些逻辑处理
...

//可以安全销毁智能指针实例
delete stuSp;

使用智能指针stuSp后,我们不必关心stu实例的销毁。只要我们不再使用stuSp实例后就主动销毁它,因为在sp内部保存了stu的指针并维护stu的引用计数,在sp的析构函数中会判断stu的引用数是否为0,如果为0就会销毁stu实例。

下面对sp的实现一探究竟:

//frameworks/rs/cpp/util/StrongPointer.h

//一个普通构造函数
//将传入的对象赋值给m_ptr变量,并调用其incStrong函数,增加其引用计数
template<typename T>
sp<T>::sp(T* other) : m_ptr(other)
{
    if (other) other->incStrong(this);
}

//析构函数
//调用m_ptr对象的decStrong函数,减少引用计数。
//decStrong函数内部会判断计数为0时,就会销毁该对象
template<typename T> 
sp<T>::~sp()
{
    if (m_ptr) m_ptr->decStrong(this);
}

//提供了三种获取原始指针的方式:星号、右箭头、get()函数
//也就是说我可以像使用原始指针那样使用使用强指针:stuSp* 等价于 stu*
inline  T&      operator* () const  { re
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值