2015年(29)
分类: C/C++
2015-04-20 22:28:23
智能指针的作用:智能指针在退出某个作用域时,能够将在对中开辟的空间自动释放掉,防止内存泄露。
智能指针与普通指针:
void f(){
T* pt(new T);
/*... more code ...*/
delete pt;
}
如果f()没有执行delete语句(因为过早return或者是在函数体内抛出异常)。动态分配的对象将没有被delete,一个典型的内存泄露,使其安全的一个简单方法是用一个“灵巧”的类指针对象包含这个指针,在其析构时,自动删除指针:
void f(){
auto_ptr<T> pt(new T);
/*... more code ...*/
}
现在这个代码将不再泄露T对象了,无论是正常函数结束还是因为异常。因为pt的析构函数总是在退栈过程中被调用,类似的,auto_ptr可以被用来安全的包容指针。
class C{
public:
C();
/*......*/
private:
auto_ptr<A> p_a;
};
//file c.cpp
C::C():p_a(new A){}
现在,析构函数不再需要删除p_a指针,因为auto_ptr会自动处理它。
如下为智能指针的使用案例:
#include
using namespace std;
class A
{
public:
A(){cout << "A()" << endl;}
~A(){cout << "~A()" << endl;}
void AShow(){cout << "This is AShow" << endl;}
};
void fun()
{
auto_ptr<A> pa(new A);
pa->AShow();
}
int main()
{
fun();
return 0;
}
输出如下:
A()
This is AShow
~A()
下面再来看一段代码,这段代码通过一个函数产生一个智能指针,并返回。
auto_ptr<A> GetAPtr()
{
return auto_ptr<A>(new A);
}
int main()
{
auto_ptr<A> pa = GetAPtr();
pa->AShow();
return 0;
}
输出的结果和上面一样,这里有个问题,在GetAPtr中,return的内容不进行强制类型转换是否可以,如下:return new A;
答案是不可行的,因为auto_ptr的构造函数定义如下:
explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()
: _Myptr(_Ptr)
{ // construct from object pointer
}
大家知道,定义为explicit的构造函数不能用于隐式转换,所以,必须通过显示的强制类型转换实现。
下面,来自己实现一个智能指针类,并且,构造函数不为explicit类型。代码如下:
template<typename T>
class my_auto_ptr
{
public:
my_auto_ptr(T* ptr):m_ptr(ptr){}
~my_auto_ptr(){if(m_ptr)delete m_ptr;}
T* operator->(){return m_ptr;}
T& operator*(){return *m_ptr;}
private:
T* m_ptr;
};
int main()
{
my_auto_ptr<A> pa(new A);
pa->AShow();
return 0;
}
代码很简单吧,输出为:
A()
This is AShow
~A()
和前面的一模一样。当然,我这边的代码只是把主要的部分给写了,真实的智能指针要比这个复杂一些,就不深究了。
此时重写GetAPtr函数如下:
my_auto_ptr<A> GetAPtr()
{
return new A;
}
int main()
{
my_auto_ptr<A> pa = GetAPtr();
pa->AShow();
return 0;
}
现在就不用显式转换了,编译能顺利通过。