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

最近看到项目中用到很多智能指针,之前没怎么学习,正好看到一句代码大全作者说的话,“如果你还没有养成使用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.) 问题集合


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值