智能指针的释放_看完这篇,别再说不会智能指针了
C++智能指針
一、智能指針的作用
上一篇介紹了內(nèi)存池的原理和實(shí)現(xiàn),詳情請(qǐng)見(jiàn)內(nèi)存池設(shè)計(jì)與實(shí)現(xiàn);
內(nèi)存池可以幫助我們有效的對(duì)內(nèi)存進(jìn)行管理,智能指針可以很方便的管理指針,避免出現(xiàn)內(nèi)存泄漏;
智能指針的作用
智能指針的作用:智能指針可以幫助我們避免在申請(qǐng)空間后忘記釋放造成內(nèi)存泄漏的問(wèn)題;因?yàn)橹悄苤羔槺旧硎且粋€(gè)類(后面也會(huì)自己實(shí)現(xiàn)一下),當(dāng)出了類的作用域的時(shí)候,類會(huì)調(diào)用析構(gòu)函數(shù)進(jìn)行釋放資源。所以智能指針的作用原理就是在函數(shù)結(jié)束時(shí)自動(dòng)釋放內(nèi)存空間,不需要手動(dòng)釋放內(nèi)存空間。
二、智能指針的原理
我們這里的指針指針主要指的是shared_ptr,這也是一種引用計(jì)數(shù)型智能指針,引用計(jì)數(shù)顧名思義就是在內(nèi)存中記錄有多少個(gè)智能指針被引用,新增一個(gè)引用計(jì)數(shù)加一,過(guò)期引用計(jì)數(shù)則減一,當(dāng)引用計(jì)數(shù)為0的時(shí)候,
智能指針才會(huì)釋放資源;
案例一
#include?#include?
using?namespace?std;
class?A
{
public:
?A()
?{
??cout?<"A?Constructor"?<endl;
?}
?~A()
?{
??cout?<"A?Destruct"?<endl;
?}
};
int?main(){
?shared_ptr?p?=?make_shared();cout?<"count:"<endl;return?0;
}
結(jié)果:
root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/demo4#?./test1?A?Constructor
count:1
A?Destruct
我們?cè)僭黾右粋€(gè)傳參,看一下引用計(jì)數(shù):
案例二
#include?#include?
using?namespace?std;
class?A
{
public:
?A()
?{
??cout?<"A?Constructor"?<endl;
?}
?~A()
?{
??cout?<"A?Destruct"?<endl;
?}
};
void?fun(shared_ptrp){???
????cout<<"fun?count:"<endl;
}int?main(){shared_ptr?p?=?make_shared();cout?<"count:"<endl;
????fun(p);cout?<"count:"<endl;return?0;
}
結(jié)果:
root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/demo4#?./test1?A?Constructor
count:1
fun?count:2
count:1
A?Destruct
通過(guò)上面的兩個(gè)例子,我們驗(yàn)證了最開(kāi)始說(shuō)的:智能指針本身是一個(gè)類(后面也會(huì)自己實(shí)現(xiàn)一下),當(dāng)出了類的作用域的時(shí)候,類會(huì)調(diào)用析構(gòu)函數(shù)進(jìn)行釋放資源;
三、智能指針的使用
智能指針的使用比較簡(jiǎn)單,在我們程序中需要包含頭文件:
#include?注意:智能指針是C++11 的標(biāo)準(zhǔn),在編譯的時(shí)候需要加上 -std=c++11 的編譯參數(shù);
使用智能指針初始化有幾種方式,new和make_shared,這里推薦使用make_shared,原因是:make_shared標(biāo)準(zhǔn)庫(kù)函數(shù),是最安全的分配和使用動(dòng)態(tài)內(nèi)存的方法,此函數(shù)在動(dòng)態(tài)內(nèi)存中分配一個(gè)對(duì)象并初始化它,返回指向此對(duì)象的shared_ptr;頭文件和share_ptr相同。
簡(jiǎn)單給個(gè)案例:
案例三
#include?#include?
using?namespace?std;
class?A
{
public:
????A(int?count)
????{
????????_nCount?=?count;
????}
????~A(){}
????void?Print(){
????????cout<<"count:"<<_ncount>endl;
????}private:int?_nCount;
};int?main(){???shared_ptrp?=?make_shared(10);
????p->Print();return?0;
}
編譯過(guò)程;
root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/demo4# g++ -std=c++11 test2.cpp -o test2root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/demo4# ./test2
count:10
四、智能指針使用注意項(xiàng)
我們先來(lái)看一段代碼:
案例四
#include?#include?
using?namespace?std;
class?B;
class?A
{
public:
????shared_ptr_pb;
};class?B
{public:shared_ptr_pa;
};int?main(){shared_ptrpa?=?make_shared();shared_ptrpb?=?make_shared();cout<<"pa?count:"<endl;cout<<"pb?count:"<endl;
????pa->_pb?=?pb;
????pb->_pa?=?pa;cout<<"pa?count:"<endl;cout<<"pb?count:"<endl;return?0;
}
結(jié)果;
root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/demo4# g++ -std=c++11 test3.cpp -o test3root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/demo4# ./test3
pa count:1
pb count:1
pa count:2
pb count:2
會(huì)發(fā)現(xiàn),最終的引用計(jì)數(shù)為2,那么結(jié)束后,引用計(jì)數(shù)不為0,他們?cè)诙焉系目臻g不會(huì)被釋放,這就是常說(shuō)的循環(huán)引用;
當(dāng)然,這不是無(wú)解的,我們可以另外一種只能指針,只不過(guò)這是種弱指針---weak_ptr,這種指針不會(huì)增加引用計(jì)數(shù),配合shared_ptr,可謂是郎才女貌,皆大歡喜呀!
案例五
#include?#include?
using?namespace?std;
class?B;
class?A
{
public:
????weak_ptr_pb;
};class?B
{public:
????weak_ptr_pa;
};int?main(){shared_ptrpa?=?make_shared();shared_ptrpb?=?make_shared();cout<<"pa?count:"<endl;cout<<"pb?count:"<endl;
????pa->_pb?=?pb;
????pb->_pa?=?pa;cout<<"pa?count:"<endl;cout<<"pb?count:"<endl;return?0;
}
結(jié)果:
root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/demo4# g++ -std=c++11 test3.cpp -o test3root@iZuf67on1pthsuih96udyfZ:~/C++/Net_C++/demo4# ./test3
pa count:1
pb count:1
pa count:1
pb count:1
很清晰的發(fā)現(xiàn),在最后互相引用的時(shí)候,引用計(jì)數(shù)器沒(méi)有加一,最后出作用域的時(shí)候就會(huì)調(diào)用析構(gòu)函數(shù),進(jìn)行內(nèi)存釋放;
五、智能指針的實(shí)現(xiàn)
實(shí)現(xiàn)智能指針,無(wú)論是在面試還是深刻理解智能指針?lè)矫?#xff0c;對(duì)我們幫助都是非常大的,理解了上面的原理,我們動(dòng)手實(shí)現(xiàn)一個(gè)智能指針:
智能指針實(shí)現(xiàn)代碼
#include?using?namespace?std;
template<class?T>class?SmartPoint
{
public:
?//構(gòu)造函數(shù)
?SmartPoint(T*?p=NULL)
?{
??_ptr?=?p;
??if?(p?!=?NULL)
??{
???_count?=?1;
??}
??else
??{
???_count?=?0;
??}
?}
?//析構(gòu)函數(shù)
?~SmartPoint()
?{
??if?(--_count?==?0)
??{
???delete?_ptr;
??}
?}
?//拷貝構(gòu)造函數(shù)
?SmartPoint(const?SmartPoint&?src)
?{
??if?(this?!=?&src)
??{
???_ptr?=?src._ptr;
???_count?=?src._count;
???_count++;
??}
?}
?//重載賦值操作符
?SmartPoint&?operator=(const?SmartPoint&?src)
?{
??if?(_ptr?==?src._ptr)
??{
???return?*this;
??}
??if?(_ptr)
??{
???_count--;
???if?(_count?==?0)
???{
????delete?_ptr;
???}
??}
??_ptr?=?src._ptr;
??_count?=?src._count;
??_count++;
??return?*this;
?}
?//重載操作符
?T*?operator?->()
?{
??if?(_ptr)
???return?_ptr;
?}
?//重載操作符
?T&?operator?*()
?{
??if?(_ptr)
???return?*_ptr;
?}
?size_t?use_count()
?{
??return?_count;
?}
private:
?T*?_ptr;
?size_t?_count;
};
void?Use(SmartPoint<char>?p){
?int?n?=?p.use_count();
}
int?main(){
?SmartPoint<char>sp1(new?char);
?Use(sp1);
?SmartPoint<char>sp2(sp1);
?SmartPoint<char>sp3;
?sp3?=?sp1;
?int?n?=?sp1.use_count();
?return?0;
}
往期精彩文章推薦
- 內(nèi)存池設(shè)計(jì)與實(shí)現(xiàn)
- 恭喜你!發(fā)現(xiàn)寶藏一份--技術(shù)文章匯總
- C++11 計(jì)時(shí)器!真香
- 我們需要懂得CMake文件
想了解學(xué)習(xí)更多C++后臺(tái)服務(wù)器方面的知識(shí),請(qǐng)關(guān)注:微信公眾號(hào):====**CPP后臺(tái)服務(wù)器開(kāi)發(fā)**====
掃碼CPP后臺(tái)服務(wù)器開(kāi)發(fā)轉(zhuǎn)載是一種動(dòng)力 分享是一種美德
總結(jié)
以上是生活随笔為你收集整理的智能指针的释放_看完这篇,别再说不会智能指针了的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python自然语言分析 何翠仪_如何用
- 下一篇: 对比两个字符串相等_字符串匹配问题