• 3.9 C++高级编程_Android弱指针的引入


    上一节简单介绍了安卓的轻量级指针,它的优点就是代码简单,使用方便

    但是,它也有一个缺点,没有办法处理一些复杂的情况

    比如说有两个智能指针 A 和 B,它们互相引用,即A引用到B,B也引用到A。

    那么我们将无法释放A和B,因为A引用了B,B的引用计数会加1,同理A的引用计数也会加1。

    这样,当我们尝试释放A或B的时候,引用计数永远也不会为0,即A和B永远也不会释放。

    修改代码,在Person类中增加两个sp类成员,father和son,并且增加两个成员函数setSon和setFather。

    修改测试函数,创建两个sp 对象father 和 son,它们就相当于开头描述的A和B。

    然后分别调用 setSon和 setFather函数,让他们互相引用。

     

    在main函数中调用测试函数。

     

    编译测试,发现只调用了Person类的构造函数,对应的析构函数没有调用,也就是说father和son在程序执行完毕后,没有释放。

    修改test_func函数,让它们没有相互引用。

    编译测试,此时Person类的析构函数会被调用。

    先来分析一下构造函数和析构函数被调用的过程。

    • 构造时:如果对象里含有其他对象成员,那么构造时先构造所包含的其他对象成员,再构造对象本身;
    • 析构时:顺序与构造函数相反。

    当执行 sp father = new Person(); 时,实际上有四个构造函数被调用:

    1. Person对象里的father先被构造;
    2. Person对象里的Son被构造;
    3. Person对象本身被构造;
    4. father对象本身被构造;

    由于没有传入参数,所以会调用的构造函数分别是:

    1. Person对象里的father先被构造;—— inline sp() : m_ptr(0) { }
    2. Person对象里的Son被构造; —— inline sp() : m_ptr(0) { }
    3. Person对象本身被构造; —— Person()
    4. father对象本身被构造;—— sp::sp(T* other)

    其中,inline sp() : m_ptr(0) { } 没有做什么操作,只是简单的初始化一下私有成员m_ptr;Person()会输出一个调试信息;而sp::sp(T* other)则会调用 incStrong函数,将引用计数值mCount 加1。

    最终,引用计数值mCount为1。

     

     

     

    同理,当执行 sp son = new Person(); 后,son的引用计数值也为1。

    再来分析一下 father->setSon(son);

    会导致Person类中setSon函数被调用,由于sp类中对“=”进行了重定向,所以 this->son = other; 实际上执行的是 sp& operator = (const sp& other);

    在重载函数中会将son的引用计数加1,之后son的引用计数就会等于2。

     

    即 father->setSon(son); 执行完以后,son对应的Person的引用计数为2。

    同理,son->setFather(father); 执行完以后,father对应的Person的引用计数为2。

    最后,当函数执行完要退出时,由于son和father对应的Person的引用计数没有减为0,所以不会调用对应的Person类的析构函数。

    问题的实质在于,father 引用了 son,father 可以决定 son 的生死,同理,son 也可以决定 father 的生死。

    要想杀死 father,必须先杀死father的引用son;要想杀死son,必须先杀死son的引用father。这就变成了一个死锁,最终导致谁都死不了。

    像这种A引用B,并且A可以决定B的生死的引用,称为强引用,或者强指针。

    对应的,A引用B,但是A不可以决定B的生死的引用,称为弱引用,或者弱指针。

    本节问题的根源就是使用的是强引用,如果使用的是弱引用,那么就不会有这个问题。

  • 相关阅读:
    libevent学习——辅助类型和函数
    戴森美发科技,呵护头皮水分0流失 戴森Supersonic™吹风机的头皮功效试验结果经中轻日用化学检验认证所确认
    Go For Web:踏入Web大门的第一步——Web 的工作方式
    ChatGPT遭受匿名苏丹组织DDoS攻击:网络安全在AI时代的新挑战
    线性预测和自回归建模
    批量将文件名称符合要求的文件自动复制到新文件夹:Python实现
    万数藏:国内首家影视IP艺术数藏平台今日上线
    所有API接口分类,淘宝/天猫API、1688API、拼多多API、京东API、各大电商API接口及测试平台
    S-RPN: Sampling-balanced region proposal network for small crop pest detection
    力扣刷题 day54:10-24
  • 原文地址:https://blog.csdn.net/qq_33141353/article/details/126515546