C/C++ 日常学习总结(第二十一篇)智能指针shared_ptr

来源:互联网 发布:.net域名崛起 编辑:程序博客网 时间:2024/06/06 02:20

最近看到项目中用到很多智能指针,之前没怎么学习,正好看到一句代码大全作者说的话,“如果你还没有养成使用auto_ptr的习惯,那么就努力吧”。听到这句话我就受刺激了。下面简单介绍下智能指针。

/*************************************************************************************

注:现在C++已经基本抛弃了auto_ptr,改为推荐使用shared_ptr。

1.auto_ptr由于他的破坏性复制语义,无法满足标准容器对元素的要求,因而不能放在

标准容器中,我们希望当容器析构时,要容器中的指针元素自动删除,会显得比较繁琐。


2.boost库提供了一个新型指针shard_ptr,它解决了多指针间共享对象所有权的问题,同时

也满足容器对元素的要求,因而可以安全地放入容器中。

*************************************************************************************/

1.auto_ptr

用指针申请动态内存时,如果不释放内存就进行销毁,那就会造成内存泄露。通过在离开作用域的时候自动释放内存,auto_ptr能避免很多与常规指针相关的内存泄露问题。

int main(){        std::string *pStr = new string("auto_ptr");      *pStr+="C++";      cout<<*pStr<<endl;      return 0;}
#include<memory>int main(){        std::tr1::shared_ptr<string> pStr(new string("auto_ptr"));      *pStr+="C++";      cout<<*pStr<<endl;      return 0;}

第二段代码中用的是shared_ptr,顺手写了,如果用auto_ptr,直接替换就行了。


2.shared_ptr

shared_ptr有个“引用计数”的概念,我的理解就是多个变量指向的同一个内存地址,就跟引用有点像,是别称。但引用计数变成0时,这个对象就被自动删除。

class CShared{public:    CShared(std::tr1::shared_ptr<int> p):m_pshare(p)    {    }    ~CShared()    {    }    void CSharedPrint()    {        printf("shardcount=%d,*m_pshare=%d\n",m_pshare.use_count(),*m_pshare);    }private:    std::tr1::shared_ptr<int> m_pshare;};void main(){    std::tr1::shared_ptr<int> pnew(new int(1000));    CShared share1(pnew),share2(pnew);    share1.CSharedPrint();//3,1000    share2.CSharedPrint();//3,1000    *pnew = 20;    print_fun(pnew);//3,20---------4.20    share1.CSharedPrint();//3,20}


3.将shared_ptr应用于标准容器的用法

typedef std::tr1::shared_ptr<int>   IntPtr;typedef std::vector<IntPtr>   vor_IntPtr;vor_IntPtr   vip(10);
#include <boost/make_shared.hpp> int main()  {      typedef vector<shared_ptr<int> > vs;        //一个持有shared_ptr的标准容器类型      vs v(10);                                   //声明一个拥有10个元素的容器,元素被初始化为空指针       int i = 0;      for (vs::iterator pos = v.begin(); pos != v.end(); ++pos)      {          (*pos) = make_shared<int>(++i);     //使用工厂函数赋值          cout << *(*pos) << ", ";            //输出值      }      cout << endl;       shared_ptr<int> p = v[9];      *p = 100;      cout << *v[9] << endl;  } 

vs2008创建的c++项目中用到了std::tr1::shared_ptr,编译时报错:error C2039: “shared_ptr”: 不是“std::tr1”的成员。
原因:未安装vs2008 SP1



4.使用规则

这个是在网上看到的,归结几点在这边,不是很全。shared_ptr不是绝对安全的。

(1)..不要构造一个临时的shared_ptr作为函数的参数。如下列代码则可能导致内存泄漏:

void test(){   foo(boost::shared_ptr<implementation>(new implementation()),g());}

正确的用法为
void test(){   boost::shared_ptr<implementation> sp (new implementation());  foo(sp,g());}

可能的过程是先new int,然后调g( ),g( )发生异常,shared_ptr<int>没有创建,int内存泄露,这个是boost文档上特地注明的标准bad Practices。Effective C++ Third Edition 条款17 有讲到。


(2.)不要把一个原生指针给多个shared_ptr管理

int* ptr = new int;shared_ptr<int> p1(ptr);shared_ptr<int> p2(ptr); //logic error

ptr对象被删除了2次
这种问题比喻成“二龙治水”,在原生指针中也同样可能发生。

(3.)问题集合


0 0
原创粉丝点击