C++11智能指针Shared_ptr陷阱

C++11智能指针Shared_ptr陷阱

目录

引言

C++11标准为C++编程语言的第三个官方标准,正式名叫ISO/IEC,在正式标准发布前,原名C++0x。它将取代C++标准第二版ISO/IEC,拓展了C++标准程序库,并且加入了大部分的C++ Technical Report 1程序库——百度百科

参考链接:C++11智能指针

本文参考此篇文章,例举了以下容易犯错的条款,如果你需要查看更详细的,可点击此链接进行查看。

C++11陷阱之易犯条款

1.不要把一个原生指针给多个shared_ptr管理

    int* ptr = new int;
    shared_ptr<int> p1(ptr);
    shared_ptr<int> p2(ptr); //logic error
    //ptr对象被删除了2次

2.不要把this指针给shared_ptr

    class Test
    {
    public:
        void GetSelf(){  m_sp =  shared_ptr<Test>(this);  }
        private:
        shared_ptr<Test> m__sp;
    };
    Test* t = new Test;
    shared_ptr<Test> sp(t);
    sp->GetSelf();
    //sp对象被删除了2次

3.shared_ptr作为被保护的对象的成员时,小心因循环引用造成无法释放资源。(解决办法,可使用weak_ptr)

weak-ptr协助shared_ptr共同协助作用。

4.不要在函数实参里创建shared_ptr

    function ( shared_ptr<int>(new int), g( ) );  
//有缺陷可能的过程是先new int,然后调g(),g()发生异常,shared_ptr<int>没有创建,int内存泄露。
    //Boost推荐写法
    shared_ptr<int> p(new int());
    f(p, g());  

5.对象内部生成shared_ptr

class Y: public boost::enable_shared_from_this<Y>
{
    boost::shared_ptr<Y> GetSelf()
    {
        return shared_from_this();
    }
};
//Boost文档说,在调用shared_from_this()之前,必须存在一个正常途径创建的shared_ptr
boost::shared_ptr<Y> spy(new Y)
boost::shared_ptr<Y> p =  spy->GetSelf(); //OK

6.对象数组用shared_array

int* pint = new int[100];
shared_array<int> p (pint ); 
//既然shared_ptr对应着delete;显然需要一个delete[]对应物shared_array

7.weak_ptr在使用前需要检查合法性。

weak_ptr<K> wp;
{
    shared_ptr<K>  sp(new K);  //sp.use_count()==1
    wp = sp; //wp不会改变引用计数,所以sp.use_count()==1
    shared_ptr<K> sp_ok = wp.lock(); //wp没有重载->操作符。只能这样取所指向的对象
}
shared_ptr<K> sp_null = wp.lock(); //sp_null .use_count()==0;
/*因为上述代码中sp和sp_ok离开了作用域,其容纳的K对象已经被释放了。得到了一个容纳NULL指针的sp_null对象。在使用wp前需要调用wp.expired()函数判断一下。因为wp还仍旧存在,虽然引用计数等于0,仍有某处“全局”性的存储块保存着这个计数信息。直到最后一个weak_ptr对象被析构,这块“堆”存储块才能被回收。否则weak_ptr无法直到自己所容纳的那个指针资源的当前状态。*/

8.不要new shared_ptr

本来shared_ptr就是为了管理指针资源的,不要又引入一个需要管理的指针资源shared_ptr*

9.尽量不要Get

class B{...};
class D : public B{ ...};  //继承层次关系

shared_ptr<B> sp (new D);    //通过隐式转换,储存D的指针。
B* b = sp.get();             //shared_ptr辛辛苦苦隐藏的原生指针就这么被刨出来了。
D* d = dynamic_cast<D*>(b);  //这是使用get的正当理由吗?

//正确的做法
shared_ptr<B> spb (new D)  ;
shared_ptr<D> spd = shared_dynamic_cast<D>(spb); //变成子类的指针
//shared_ptr在竭尽全力表演的像一个原生指针,原生指针能干的事,它也基本上能干。

//另一个同get相关的错误
shared_ptr<T> sp(new T);
shared_ptr<T> sp2( sp.get() ) ;//又一个“二龙治水”实例,指针会删2次而错误。

10.构造函数里调用shared_from_this抛例外

class Holder:public enable_shared_from_this<Holder>
{
public:
    Holder() 
    {
        shared_ptr<Holder> sp = shared_from_this();
        int x = sp.use_count();
    }
};
//同前面条款5,不符合enable_shared_from_this使用前提。

结尾

只为记录,只为分享! 愿所写能对你有所帮助。Good Good Study, Day Day Up!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值