详解C++智能指针

一、智能指针

    常规指针的缺点:

        当一个常规指针离开了作用域时,只有该指针变量本身占用的内存空间(4/8字节)会被释放,而它指向的内存空间不会自动释放,当free\delete\delete[]语句忘记执行或者无法执行,形成内存泄漏

    智能指针的优点:

       智能指针是一个封装了常规指针的类类型对象,并且重载了 * 和 ->运算符,使用起来与常规指针相近

       当智能指针离开作用域时,它的析构函数必定执行,从而在析构函数中执行释放常规指针的操作,这样就做到了自动释放的效果,从而避免内存泄漏

       智能指针是一个类模板

   

    C++STL中提供了四种智能指针:auto_ptr\shared_ptr\unique_ptr\weak_ptr,在C++98标准中只有第一个auto_ptr,C++11只支持后三个,第一个被弃用,使用会产生警告

    需要提供头文件 <memory>

    1、auto_ptr

        采用独占拥有模式,不能同时有多个auto_ptr指向同一个内存,但是不能完全实现,有时候会指向同一个内存,有隐患

        auto_ptr<int> p1(new int(123));

        auto_ptr<int> p2;   // 可以悬空

        p2 = p1;   // 允许,但p1转移所有权给p2,p1可能变成空指针

        *p1;    //  可能段错误

        注意:这种独占式不一定成立,p1是否转移给p2不确定

        使用格式:

        1、auto_ptr<类型> 对象名(new 类型名);

        2、类型* p = new 类型;

           auto_ptr<类型> 对象名(p);

   

    2、unique_ptr   独享指针

       是auto_ptr的升级,完全实现独占式拥有模式,保证同一时间中只有一个unique_ptr指向某个内存

       通过把拷贝构造、赋值操作函数声明为delete来实现不能给另一个unique_ptr对象赋值的效果

        unique_ptr<int> p1(new int);

        unique_ptr<int> p2;

        p2 = p1;   //   报错

        p2 = unique_ptr<int>(new int);

        //  允许指向匿名unique_ptr对象的内存

       

        可以通过C++的全局函数 move() 来转移内存的指向给另一个unique_ptr

        p2 = move(p1);  // 让p2指向p1原来的内存,p1一定会变成空指针,p2在改变指向之前,会先释放自己原来的内存

       

    3、shared_ptr   共享指针

        采用共享的拥有模式,可以允许多个shared_ptr指向相同内存

        当一个内存被shared_ptr指向时,内部有一个引用计数器+1

        当指向该内存的某个shared_ptr离开作用域或者改变指向或者通过reset()时,引用计数器会-1

        当该内存的引用计数器被减为0时,由最后一个离开的shared_ptr在结束前释放该内存

        相关成员函数:

            get()     获取指向内存的地址编号

            use_count()   获取引用计数器的值

            unique()    判断指向的内存是否只有一个shared_ptr指向

                        0 不独占  1 独占

            reset()   放弃对内存的指向 计数-1

        全局函数:

            val2 = move(val1)  移动val1的值和使用权给val2

            swap()   交换两个对象

       

        sharead_ptr的循环引用问题:

            当两个类(A B)中都有可以指向对方类型的shared_ptr智能指针成员变量(pB pA),并且在类外通过shared_ptr指向new出来的两个类对象(pa指向类A pb指向类B),并且让他们的成员变量pB pA 指向对方,此时构成循环引用,导致就算类对象pa pb销毁,但它们指向的对象的引用计数无法减为0(pA pB还在指向),导致无法释放对象内存,内存泄漏

   

    4、weak_ptr 弱引用指针

        weak_ptr是为了配合shared_ptr而引入的一种智能指针,它指向一个由shared_ptr管理的对象而不影响该对象的生命周期,也即是说将一个weak_ptr指向一个shared_ptr对象,或者离开时都不会改变该对象的引用计数,只有当最后一个shared_ptr离开该对象才会销毁

        weak_ptr更像是shared_ptr的一个助手,而不是独立的智能指针

        因此当发生shared_ptr的循环引用产生死锁时,可以把其中一个类的shared_ptr成员变量改为weak_ptr,即可避免产生死锁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值