智能指针RAII:资源分配及初始化,定义一个类来封装资源的分配和初始化,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放
#pragmaonce
//AutoPtr 智能指针
template<classT>
classAutoPtr
{
public:
//构造函数
AutoPtr(T*ptr)
:_ptr(ptr)
{}
//拷贝构造
//把ap1股给ap2后,再把自己置为空,不再管理这个内存空间
AutoPtr(AutoPtr<T>&ap)
:_ptr(ap._ptr)
{
ap._ptr
=NULL;
}
//赋值运算符重载
//释放ap3,让ap3指向ap2所指空间,再把ap2置空
AutoPtr<T>&
operator=(AutoPtr<T>&ap)
{
if(this!=
&ap)
{
cout <<"delete:"<<
_ptr << endl;
delete_ptr;
_ptr =ap._ptr;
ap._ptr
=NULL;
}
return*this;
}
//析勾函数
~AutoPtr()
{
if(_ptr)
{
cout <<"delete:"<<
_ptr << endl;
delete_ptr;
_ptr =NULL;
}
}
//operator*
T&
operator*()
{
return*_ptr;
}
//operator->
T*
operator->()
{
return_ptr;
}
//getPtr
T*
GetPtr()
{
return_ptr;
}
protected:
T*
_ptr;
};
// 智能指针管理一块内存的释放
// 智能指针是一个类,有类似指针的功能
structNode
{
int_data;
Node*
_next;
};
voidTestAutoPtr()
{
int*
p1 =newint(2);
int*
p2 = p1;
int*
p3;
p3 = p2;
*p1 = 10;
//会造成两次析勾,类似于浅拷贝,ap1,ap2都指向同一块内存空间,第一个析勾后,
//第二个就成为野指针
AutoPtr<int>
ap1(newint(1));
AutoPtr<int>
ap2 = ap1; //AutoPtr ap2(ap1);
//释放ap3,让ap3指向ap2所指空间,再把ap2置空
AutoPtr<int>
ap3(newint(3));
ap3 = ap2;
*ap3 = 10;
//*ap1 = 30;
AutoPtr<Node>
apNode(newNode);
apNode->_data = 10;
deletep1;
}
//AutoPtr容易出错,因为前面的指针已经置为空,存在潜在危险,没有完全达到指针的效果,
//ScopedPtr 智能指针
template<classT>
classScopedPtr
{
public:
//构造函数
ScopedPtr(T*ptr)
:_ptr(ptr)
{}
//析勾函数
~ScopedPtr()
{
if(_ptr)
{
cout <<"delete:"<<
_ptr << endl;
delete_ptr;
}
}
//重载*
T&
operator*()
{
return*_ptr;
}
//operator->
T*
operator->()
{
return_ptr;
}
//GetPtr
T*
GetPtr()
{
return_ptr;
}
protected:
//1.限定符为protected,不能进行拷贝,2.将拷贝构造和赋值运算符的重载声明出来
//不能让他调用默认的,也不能在外面定义它
ScopedPtr(constScopedPtr<T>&
sp);
ScopedPtr<T>
operator=(constScopedPtr<T>&
sp);
protected:
T*
_ptr;
};
//防止别人在类外面定义它
//template<class T>
//ScopedPtr<T>::ScopedPtr(const ScopedPtr<T>& sp)
// :_ptr(sp._ptr)
//{}
voidTestScopedPtr()
{
ScopedPtr<int>
sp1(newint(1));
//ScopedPtr<int> sp2(sp1);
}
//SharedPtr 利用引用计数来解决这个问题
template<classT>
classSharedPtr
{
public:
SharedPtr(T*ptr)
:_ptr(ptr)
, _pCount(newlong(1))
{}
~SharedPtr()
{
_Release();
}
//只是改变pcount
SharedPtr(constSharedPtr<T>&sp)
:_ptr(sp._ptr)
, _pCount(sp._pCount)
{
++(*_pCount);
}
////赋值运算符的传统写法
//SharedPtr<T>& operator=(const
SharedPtr<T>& sp)
//{
// if (this != &sp)
// {
// this->_Release();
// _pCount
= sp._pCount;
// _ptr =
sp._ptr;
// ++(*_pCount);
// }
// return *this;
//}
//现代写法
SharedPtr<T>&
operator=(SharedPtr<T>sp)
{
swap(_ptr,sp._ptr);
swap(_pCount,sp._pCount);
return*this;
}
T&
operator*()
{
return*_ptr;
}
T*
operator->()
{
return_ptr;
}
T*
GetPtr()
{
return_ptr;
}
longGetCount()
{
return*_pCount;
}
protected:
void_Release()
{
//如果指向这个的引用计数为0才delete,其他时候只是前置减减
if(--(*_pCount)
== 0)
{
delete_ptr;
delete_pCount;
}
}
protected:
T*
_ptr;
long*
_pCount;
};
voidTestSharedPtr()
{
SharedPtr<int>
sp1(newint(1));
SharedPtr<int>
sp2(sp1);
cout << sp1.GetCount() << endl;
SharedPtr<int>
sp3(newint(2));
sp3 = sp1;
}