##1. 简介
由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,造成内存泄漏。
使用C++智能指针可以有效的解决这类问题,本文中主要介绍***std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::scoped_array、boost::shared_array、boost::weak_ptr***,这六种指针的存在有效的解决new/delete问题。
2. 具体使用
我们首先编写的用来测试的类:
class Sample
{
public:
Sample(size_t Num)
{
this->m_Num = Num;
myString = "Sample";
cout<<"Sample"<<endl;
}
~Sample()
{
cout<<"~Sample"<<endl;
}
void Print()
{
cout<<"Num is:"<<m_Num<<" myString is:"<<myString.c_str()<<endl;
}
public:
size_t m_Num;
string myString;
};
###1.std::auto_ptr
std::auto_ptr 属于 STL,当然在 namespace std 中,包含头文件 #include 便可以使用。std::auto_ptr 能够方便的管理单个堆内存对象。
首先我们写一段代码进行分析:
void Test1()
{
auto_ptr<Sample> au(new Sample(45));
if (au.get()) //判断指针是否为空
{
au->Print(); //调用输出函数
au->myString += " is "; //修改myString值
au.get()->Print(); //调用打印函数
au.get()->myString += "Called!!!"; //使用get获取对象指针来修改对象
au->Print(); //打印
}
}
运行结果如下:
代码中get函数可以获得对象的指针,我们来查看get的源码:
_Ty *get() const _THROW0()
{ // return wrapped pointer
return (_Myptr);
}
从代码中可以看出返回资源对象的指针,即new 出来Sample对象的指针。
从运行结果中可以看出new 出来的对象已经得到正确释放。
void Test2()
{
auto_ptr<Sample> au(new Sample(45));
if (au.get()) //判断指针是否为空
{
au->Print(); //调用输出函数
au->myString += " is "; //修改myString值
au.get()->Print(); //调用打印函数
au.get()->myString += "Called!!!"; //使用get获取对象指针来修改对象
au->Print(); //打印
auto_ptr<Sample> other = au; //赋值运算
other->Print(); //new对象打印
au->Print(); //old对象打印
}
}
迫不及待来看看运行结果吧
哇哦,程序挂了,为甚么呢,我们来看看operator=的源码:
_Myt& operator=(auto_ptr_ref<_Ty> _Right) _THROW0()
{ // assign compatible _Right._Ref (assume pointer)
_Ty *_Ptr = _Right._Ref;
_Right._Ref = 0; // release old
reset(_Ptr); // set new
return (*this);
}
通过查看源码,恍然大悟,原来operator=在赋值过程中获取内存管理的控制权,将