灵巧指针即自动指针。它的引入主要是为了减少内存的泄露。为什么这样说呢?
举个简单的例子。
viod fun()
{
int *p=new int;
int *p1=new int;
delete p;
delete p1;
}
int main()
{
fun();
}
如果这个程序正常执行了,当然没有什么问题了。但是如果释放p时出现了异常呢?那么我们的p1就无法正常的释放了。内存的泄露就在这时发生了。但是如果我们用了灵巧指针这个问题就轻而易举的解决了。
灵巧指针是什么呢?他为什么有如此强大的功能呢?
最简单的灵巧指针就是一个迭代器,并且在它的析构函数中调用delete函数来释放他所申请的空间。
我们再来看看上面的这个例子,假如我们的p释放失败。也就是说出现了异常。我们的这个函数所有的局部变量都要被析构。如果我们使用了灵巧指针来定义p,p1那么当异常出现时,会调用他们的析构函数,从而释放他们所申请的空间。
下面还有一个很经典的例子。这个例子用灵巧指针解决而一个新的问题。
class Myclass
{
public:
Myclass() { cout<<"create Myclass"<<endl;}
~Myclass()
{
cout<<"free Myclass"<<endl;
throw 1;
}
};
int * creator()
{
Holder<int> h(new int);
Myclass x;
return h.release();
}
void main()
{
int *p=NULL;
try
{
p=creator();
}
catch(int a)
{
cout<<a<<endl;
return;
}
delete p;
}
注:1、这个例子所有的代码见2010.cpp。
2、上述代码中的release()函数的作用是让灵巧指针将自己的所开辟空间的地址返回,并将自己的指针置为空。
int * creator()
{
Holder<int> h(new int);
Myclass x;
return h.release();
}
这个函数的本意是,把灵巧指针h所产生的空间返回给指针p。但是灵巧指针在析构的时候就会调用释放函数将自己所申请的空间释放掉。所以我们需要一个release()函数来将灵巧指针置空,并将其申请空间的地址返回。所以当return时我们调用了h.release()函数并将h申请空间的地址返回给一个临时无名变量。然后进行局部变量的析构。
问题也随之而来。析构临时x时如果发生异常的话,又会产生h的内存泄露。因为h所申请空间的地址已经给了临时无名变量。但是这个临时无名对象的生存期却在这个函数之外。这就产生h的内存泄露。因为当发生异常是我们不会去掉用将临时无名变量赋值给p的这个操作。自然就不会析构这个临时无名变量。那么我们的内存泄露了。
2010.cpp
#include<iostream.h>
template<typename T>
void swap(T &x, T &y)
{
T z=x;
x=y;
y=z;
}
template<typename T> class Trule;
template<typename T> class Holder
{
private:
T *ptr;
public:
Holder():ptr(0) {}
explicit Holder(T *p):ptr(p) {}
~Holder()
{
cout<<"free Holder ptr"<< ptr<<endl;
delete ptr;
}
Holder(Trule<T> const &t)
{
ptr=t.ptr;
const_cast<Trule<T> &>(t).ptr=0;
}
Holder & operator=(T *p)
{
delete ptr;
ptr=p;
return *this;
}
Holder<T> & operator=(Trule<T> const &t)
{
delete ptr;
ptr=t.ptr;
const_cast<Trule<T> &>(t).ptr=0;
return *this;
}
T& operator*() const
{
return *ptr;
}
T * operator->() const
{
return ptr;
}
T * get() const
{
return ptr;
}
T* release()
{
T *ret=ptr;
ptr=0;
cout<<"holder release"<<endl;
return ret;
}
void exchange_with(T *&p)
{
swap(ptr,p);
}
T * get_pointer()
{
return ptr;
}
private:
Holder(const Holder<T> & );
Holder<T> & operator=(Holder<T> const&);
};
////////////////////////////////////////////
template<typename T> class Trule
{
private:
T *ptr;
public:
Trule(Holder<T> &h)
{
ptr=h.get();
h.release();
}////////////////////////////
Trule(Trule<T> const &t)
{
ptr=t.ptr;
const_cast<Trule<T> &>(t).ptr=0;
}///////////////////////////////////
~Trule()
{
delete ptr;
}
private:
// Trule(Trule<T> &);
Trule<T> &operator=(Trule<T> &);
friend class Holder<T>;
};
/////////////////////
class Something
{
public:
Something()
{
cout<<"Create Something"<<this<<endl;
}
~Something()
{
cout<<"free Something"<<this<<endl;
}
void profrom()
{
throw 1;
}
};
class Myclass
{
public:
Myclass() { cout<<"create Myclass"<<endl;}
~Myclass()
{
cout<<"free Myclass"<<endl;
throw 1;
}
};
Trule<Something> creator()
{
Holder<Something> h(new Something());
Myclass x;
return h;
}// Trule<Something> xx(h);
void main()
{
try
{
Holder<Something> ptr(creator());
}
catch(int a)
{
cout<<a<<endl;
}
}
斑竹能不能给个邀请码,让我更好的学习~~谢谢了
[课程]Android-CTF解题方法汇总!