一 Boost::smart_Ptr
我们学习C++都知道智能指针,例如STL中的std::auto_ptr,但是为什么要使用智能指针,使用它能带给我们什么好处呢?
最简单的使用智能指针可以不会因为忘记delete指针而造成内存泄露。还有如果我们开发或者使用第三方的lib中的某些函数需要返回指针,这样的返回的指针被client使用的时候,lib就会失去对返回的指针的控制,这样delete的指针的任务一般就会交给调用方client,但是如果client忘记调用delete或是调用的时机不正确,都有可能导致问题,在这种情况下就最好使用智能指针。还有使用智能指针可以保证异常安全,保证程序在有异常抛出时仍然无内存泄露。
std::auto_ptr很多的时候并不能满足我们的要求,比如她不能用在STL的container中。boost的smart_ptr中提供了4种智能指针和2种智能指针数组来作为std::auto_ptr的补充。
shared_ptr
scoped_ptr
weak_ptr
intrusive_ptr
scoped_array
shared_array
二 源码剖析
通过上面的分析,下面主要介绍我们最常用也最有用的shared_ptr智能指针。(智能指针的实现,其实最重要的是就是重载->和*运算符)
下面是shared_ptr的头文件:
template<classTy>classshared_ptr{
public:
typedef Ty element_type;
shared_ptr();
template<classOther>
explicitshared_ptr(Otherptr);
template<classOther,classD>
shared_ptr(Otherptr, D dtor);
shared_ptr(constshared_ptr&sp);
template<classOther>
shared_ptr(constshared_ptr<Other>&sp);
template<classOther>
shared_ptr(constweak_ptr<Other>&wp);
template<classOther>
shared_ptr(conststd::auto_ptr<Other>&ap);
~shared_ptr();
shared_ptr&operator=(constshared_ptr&sp);
template<classOther>
shared_ptr&operator=(constshared_ptr<Other>&sp);
template<classOther>
shared_ptr&operator=(auto_ptr<Other>&ap);
voidswap(shared_ptr&s);
voidreset();
template<classOther>
voidreset(Otherptr);
template<classOther,classD>
voidreset(Otherptr, D dtor);
Tyget()const;
Ty&operator()const;
Tyoperator->()const;
longuse_count()const;
boolunique()const;
operatorboolean-type()const;
};
1)构造函数,可以通过一般指针,std::auto_ptr,boost::shared_ptr,boost::weak_ptr来构造,还可以构造的时候指定如果delete指针。
2)拷贝构造函数
3)get(), 得到boost::shared_ptr所封装的指针。
4),得到boost::shared_ptr所封装指针的值。
5)->,用于直接调用指针的成员。
6)reset(), 用于重设boost::shared_ptr,或设为空。
7) swap(), 用于交换2个boost::shared_ptr.
8) use_count(), use_count 函数返回指针的引用计数。
9) unique(),这个函数在shared_ptr是它所保存指针的唯一拥有者时返回 true ;否则返回 false。 unique 不会抛出异常。
三 实例
1)构造,拷贝构造,赋值,get,,->, reset, swap:
#include"boost/shared_ptr.hpp"
#include<cassert>
#include<iostream>
classA
{
boost::shared_ptr<int>no_;
public:
A(boost::shared_ptr<int>no) : no_(no){}
voidvalue(inti){no_=i; }
};
classB
{
boost::shared_ptr<int>no_;
public:
B(boost::shared_ptr<int>no) : no_(no){}
intvalue()const{returnno_; }
};
structdeleter
{
voidoperator()(inti)
{
std::cout<<"destroying resource at"
<<(void)i<<'\n';
delete i;
}
};
structS
{
intmember;
};
intmain()
{
//test for constructor
boost::shared_ptr<int>sp;
boost::shared_ptr<int>sp2((int)0);
{
boost::shared_ptr<int>sp3(newint(3), deleter());
}
std::auto_ptr<int>temp(newint(10));
boost::shared_ptr<int>sp4(temp);
boost::shared_ptr<int>temp2(newint(14));
boost::shared_ptr<int>sp5(temp2);
//test for using the shared_ptr(get,->,)
intip=newint(3);
std::cout<<(void)ip<<'\n';
boost::shared_ptr<int>sp6(ip);
std::cout<<(void)sp6.get()<<'\n';
intip2=newint(3);
std::cout<<(void)ip2<<'\n';
boost::shared_ptr<int>sp7(ip2);
std::cout<<sp7<<'\n';
std::cout<<(void)&sp7<<'\n';
Ss=newS;
s->member=4;
boost::shared_ptr<S>sp8(s);
std::cout<<sp8->member<<'\n';
//test for assign
std::cout<<std::boolalpha;
boost::shared_ptr<int>sp9(newint(0));
boost::shared_ptr<int>sp10=sp9;
std::cout<<"sp0 == sp1:"<<(sp9==sp10)<<'\n';
std::cout<<"sp0 != sp2:"<<(sp9!=sp10)<<'\n';
//test funcion: reset and swap
boost::shared_ptr<int>sp11 (newint(0));
boost::shared_ptr<int>sp12 (newint(1));
sp11. swap (sp12);
std::cout<<sp11<<sp12<<std::endl;
boost::swap(sp11, sp12);
std::cout<<sp11<<sp12<<std::endl;
boost::shared_ptr<int>sp0;
sp0.reset();
boost::shared_ptr<int>sp01(newint(1));
std::cout<<sp01<<std::endl;
sp01.reset();
//std::cout << sp01 <<std::endl;//error
sp01.reset(newint(100));
std::cout<<sp01<<std::endl;
//test for query shared_ptr's state (use_count,unique)
typedef boost::shared_ptr<int>spi;
spi sp13 ;
std::cout<<"empty object:"<<sp13.use_count()<<'\n';
spi sp14 ((int)0);
std::cout<<"null pointer:"<<sp14.use_count()<<'\n';
spi sp15 (newint);
std::cout<<"one object:"<<sp15.use_count()<<'\n';
{
spi sp16(sp15);
std::cout<<"two objects:"<<sp15.use_count()<<'\n';
std::cout<<"two objects:"<<sp16.use_count()<<'\n';
}
std::cout<<"one object:"<<sp15.use_count()<<'\n';
std::cout<<std::boolalpha;
spi sp17;
std::cout<<"empty object:"<<sp17.unique()<<'\n';
spi sp18((int*)0);
std::cout<<"null pointer:"<<sp18.unique()<<'\n';
spi sp19(newint);
std::cout<<"one object:"<<sp19.unique()<<'\n';
{
spi sp20(sp19);
std::cout<<"two objects:"<<sp19.unique()<<'\n';
std::cout<<"two objects:"<<sp20.unique()<<'\n';
}
std::cout<<"one object:"<<sp19.unique()<<'\n';
}
2) 在STL容器中的使用:
#include"boost/shared_ptr.hpp"
#include<vector>
#include<iostream>
classA
{
public:
virtualvoidsing()
{
std::cout<<"A::sing"<<std::endl;
}
protected:
virtual~A()
{std::cout<<"~A"<<std::endl;};
};
classB :publicA
{
public:
virtualvoidsing()
{
std::cout<<"B:sing"<<std::endl;
}
virtual~B()
{std::cout<<"~B"<<std::endl;}
};
boost::shared_ptr<A>createA()
{
boost::shared_ptr<A>p(newB());
returnp;
}
intmain()
{
typedef std::vector<boost::shared_ptr<A>>container_type;
typedef container_type::iterator iterator;
container_type container;
for(inti=0;i<10;++i)
{
container.push_back(createA());
}
std::cout<<"The choir is gathered: \n";
iterator end=container.end();
for(iterator it=container.begin();it!=end;++it)
{ (*it)->sing(); }
}
四 注意
五 参考
1)Beyond the C++ Standard Library: An Introduction to Boost
2)boost在线document
原文链接: https://www.cnblogs.com/lzjsky/archive/2011/01/13/1934720.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/20029
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!