0
点赞
收藏
分享

微信扫一扫

C++智能指针总结


智能指针RAII:资源分配及初始化,定义一个类来封装资源的分配和初始化,在构造函数完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放




#pragma
once


//AutoPtr 智能指针


template
<
class
T
>


class
AutoPtr


{


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;


};





// 智能指针管理一块内存的释放


// 智能指针是一个类,有类似指针的功能


struct
Node


{



int
_data;



Node
* _next;


};





void
TestAutoPtr()


{



int
* p1 =
new
int
(2);



int
* p2 = p1;



int
* p3;


p3 = p2;





*p1 = 10;



//会造成两次析勾,类似于浅拷贝,ap1,ap2都指向同一块内存空间,第一个析勾后,



//第二个就成为野指针



AutoPtr
<
int
> ap1(
new
int
(1));



AutoPtr
<
int
> ap2 = ap1;
//AutoPtr ap2(ap1);



//释放ap3,让ap3指向ap2所指空间,再把ap2置空



AutoPtr
<
int
> ap3(
new
int
(3));


ap3 = ap2;


*ap3 = 10;



//*ap1 = 30;






AutoPtr
<
Node
> apNode(
new
Node
);


apNode->_data = 10;






delete
p1;


}


//AutoPtr容易出错,因为前面的指针已经置为空,存在潜在危险,没有完全达到指针的效果,











//ScopedPtr 智能指针


template
<
class
T
>


class
ScopedPtr


{


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(
const
ScopedPtr
<
T
>& sp);



ScopedPtr
<
T
> operator=(
const
ScopedPtr
<
T
>& sp);





protected
:



T
* _ptr;


};





//防止别人在类外面定义它


//template<class T>


//ScopedPtr<T>::ScopedPtr(const ScopedPtr<T>& sp)


// :_ptr(sp._ptr)


//{}





void
TestScopedPtr()


{



ScopedPtr
<
int
> sp1(
new
int
(1));



//ScopedPtr<int> sp2(sp1);


}








//SharedPtr 利用引用计数来解决这个问题


template
<
class
T
>


class
SharedPtr


{


public
:


SharedPtr(
T
*
ptr
)


:_ptr(
ptr
)


, _pCount(
new
long
(1))


{}





~SharedPtr()


{


_Release();


}



//只是改变pcount


SharedPtr(
const
SharedPtr
<
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;


}






long
GetCount()


{



return
*_pCount;


}





protected
:



void
_Release()


{



//如果指向这个的引用计数为0才delete,其他时候只是前置减减



if
(--(*_pCount) == 0)


{



delete
_ptr;



delete
_pCount;


}


}





protected
:



T
* _ptr;



long
* _pCount;


};





void
TestSharedPtr()


{



SharedPtr
<
int
> sp1(
new
int
(1));



SharedPtr
<
int
> sp2(sp1);


cout << sp1.GetCount() << endl;






SharedPtr
<
int
> sp3(
new
int
(2));


sp3 = sp1;


}

举报

相关推荐

C++智能指针

C++——智能指针

【C++】智能指针

C++ 智能指针

C++进阶 智能指针

0 条评论