




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
boost常用庫(kù)使用介紹第二講第一頁(yè),共41頁(yè)。第一節(jié):C++程序員對(duì)內(nèi)存管理的苦惱1、內(nèi)存泄漏(memoryleak)2、野指針(wildpointer)3、訪問(wèn)越界(accessviolation)boost的智能指針庫(kù)就是內(nèi)存管理的強(qiáng)勁解決方案通過(guò)boost智能指針庫(kù),我們能夠高效的進(jìn)行內(nèi)存管理,解決上述問(wèn)題,同時(shí)徹底讓你忘記棧(stack),堆(heap)等內(nèi)存相關(guān)的術(shù)語(yǔ),并且還會(huì)發(fā)現(xiàn),boost為c++提供的內(nèi)存管理解決方案可能比java和c#等其他語(yǔ)言更好,更高效!2第二頁(yè),共41頁(yè)。第二節(jié):智能指針與RAII機(jī)制為了管理內(nèi)存等資源,智能指針采用RAII機(jī)制(ResourceAcquisitionIsInitialization,資源獲取既初始化)1、所有初始化操作移到對(duì)象的構(gòu)造函數(shù)中2、所有的釋放操作都放在對(duì)象的析構(gòu)函數(shù)里。3、適當(dāng)?shù)漠惓L幚泶a來(lái)應(yīng)付對(duì)象構(gòu)造期間丟出的異常這種用構(gòu)造函數(shù)申請(qǐng)資源用析構(gòu)函數(shù)釋放資源的做法或者說(shuō)技術(shù)通常被稱為“資源獲取即初始化”。這樣做的優(yōu)點(diǎn)是而易見(jiàn)的:對(duì)象創(chuàng)建后,用戶能開始正確使用對(duì)象,不用擔(dān)心對(duì)象的有效性或者是否還要作進(jìn)一步的初始化操作。
3第三頁(yè),共41頁(yè)。第三節(jié):Boost智能指針的分類:boost提供下列幾種智能指針:4第四頁(yè),共41頁(yè)。第四節(jié):shared_ptr簡(jiǎn)介1、boost::shared_ptr是一個(gè)最像指針的“智能指針”:是boost.smart_ptr中最有價(jià)值,最重要,也是最有用的類,boost庫(kù)的其他許多類庫(kù)都使用了shared_ptr,所以毫無(wú)懸念的被收入了c++11標(biāo)準(zhǔn)中去。2、boost::shared_ptr實(shí)現(xiàn)了計(jì)數(shù)引用:
它包裝了new操作符在堆上分配的動(dòng)態(tài)對(duì)象,但它實(shí)現(xiàn)了引用計(jì)數(shù),可以自由的拷貝和賦值,在任意地方共享它。當(dāng)引用計(jì)數(shù)為0時(shí),它會(huì)自動(dòng)刪除被包裝的動(dòng)態(tài)分配的對(duì)象。5第五頁(yè),共41頁(yè)。第四節(jié):shared_ptr簡(jiǎn)介3、boost::shared_ptr不需要手動(dòng)的調(diào)用類似release方法:
它不像侵入式實(shí)現(xiàn)的智能指針一樣需要手動(dòng)的調(diào)用類似release方法,全部用由shared_ptr內(nèi)部的計(jì)數(shù)器自動(dòng)增減,這一點(diǎn)是非常有用的。(COM的IUnknow接口以及boost::intrusive_ptr<T>都是基于侵入式設(shè)計(jì)的智能指針,需要手動(dòng)調(diào)用類似release方法)4、boost::shared_ptr支持所有權(quán)轉(zhuǎn)移:
并且可以安全的存儲(chǔ)在stl標(biāo)準(zhǔn)容器中,是在stl容器存儲(chǔ)指針的標(biāo)準(zhǔn)解法。例如std::vector<int*>IntVec,使用shared_ptr方式為std::vector<boost::shared_ptr<int>>IntptrVec.6第六頁(yè),共41頁(yè)。第五節(jié):shared_ptr類摘要1、構(gòu)造函數(shù),拷貝構(gòu)造函數(shù),賦值操作符以及析構(gòu)函數(shù)Template<classT>Classshared_ptr{/*******************構(gòu)造函數(shù)*******************************************/
shared_ptr();//創(chuàng)建一個(gè)持有空指針的shared_ptr,use_count()=0&&get()==NULL//獲得一個(gè)指向類型T的指針p的管理權(quán),use_count==1&&get()==p,Y類型必須能夠轉(zhuǎn)換為T類型
template<classY>explicitshared_ptr(Y*p);
//作用同上,增加了一個(gè)構(gòu)造參數(shù)D,是一個(gè)仿函數(shù)對(duì)象,代表刪除器,該構(gòu)造函數(shù)非常有用,后面會(huì)詳解
template<classY,classD>shared_ptr(Y*p,Dd);/******************拷貝構(gòu)造函數(shù)及賦值操作符重載***********************/
//調(diào)用拷貝構(gòu)造函數(shù)或賦值操作后,引用計(jì)數(shù)加1&&get()==r.get()&&use_count()==r.use_count()shared_ptr(shared_ptrconst&r);template<classY>shared_ptr(shared_ptr<Y>const&r);
shared_ptr&operator=(shared_ptrconst&r);template<classY>shared_ptr&operator=(shared_ptr<Y>const&r);/******************析構(gòu)函數(shù)*******************************************/
//引用計(jì)數(shù)會(huì)減1,如果計(jì)數(shù)器為0,get()!=NULL,有刪除器的話會(huì)調(diào)用刪除器,否則調(diào)用delete操作符~shared_ptr();}
7第七頁(yè),共41頁(yè)。第五節(jié):shared_ptr類摘要2、public成員方法和操作符Template<classT>classshared_ptr{T*get()const;//返回原始指針T&operator*()const;//返回原始指針的引用T*operator->()cosnt;//返回原始指針longuse_count()const;//返回引用計(jì)數(shù)boolunique()const;//返回use_count()==1,是否唯一operatorbool()const;//bool值轉(zhuǎn)型,可以用于條件判斷,例如if(ptr){…}voidsb)//交換原始指針
voidreset();template<classY>voidreset(Y*p);template<classY,classD>voidreset(Y*p);}
8第八頁(yè),共41頁(yè)。第六節(jié):shared_ptr的一個(gè)例子1、#include<boost/shared_ptr.hpp>2、創(chuàng)建一個(gè)shared_ptr要用到的簡(jiǎn)單類FooclassFoo{private:std::stringm_strName;Public:Foo(conststd::string&strName):m_strName(strName){}~Foo(){std::cout<<“DestructingFoowithname=“<<m_strName<<std::endl}};9第九頁(yè),共41頁(yè)。第六節(jié):shared_ptr的一個(gè)例子3、實(shí)現(xiàn)voidTest_Boost_Shared_Ptr()typedefboost::share_ptr<Foo>FooPtr;voidTest_Boost_Shared_Ptr(){//ptr1獲得Foo__1指針的所有權(quán)FooPtrptr1(newFoo(“Foo1”));//引用計(jì)數(shù)為1 assert(ptr1.use_count()==1);//ptr2指向ptr1 FooPtrptr2=ptr1;//調(diào)用shared_ptr的賦值操作符,引用計(jì)數(shù)加1 assert(ptr1.use_count()==ptr2.use_count());//兩者引用計(jì)數(shù)相同 assert(ptr1==ptr2);//shared_ptr重載==操作符,等同于ptr1.get()==ptr2.get()。 assert(ptr1.use_count()==2);//現(xiàn)在ptr1和ptr2都指向了Foo__1,因此計(jì)數(shù)器都為2
10第十頁(yè),共41頁(yè)。第六節(jié):shared_ptr的一個(gè)例子//ptr3獲得Foo__1指針的所有權(quán)FooPtrptr3=ptr2;//引用計(jì)數(shù)加1 assert(ptr1.use_count()==ptr2.use_count()&&ptr1.use_count()==ptr3.use_count()); assert(ptr1.use_count()==3&&ptr2.use_count()==3&&ptr3.use_count()==3); assert(ptr1==ptr2&&ptr1==ptr3);//現(xiàn)在我們重置ptr3,測(cè)試reset()函數(shù) ptr3.reset(); assert(ptr3.use_count()==0&&ptr3.get()==NULL); std::cout<<"ptr3引用計(jì)數(shù)為0,get()指針指向NULL,但是不會(huì)調(diào)用析構(gòu)函數(shù),因?yàn)閜tr1和ptr2都指向了原生指針"<<std::endl;assert(ptr1.use_count()==ptr2.use_count()&&ptr1.use_count()==2);assert(ptr1==ptr2&&ptr1!=ptr3);//前面ptr1和ptr2都指向了同一個(gè)對(duì)象,他們的引用計(jì)數(shù)都為2,現(xiàn)在創(chuàng)建一個(gè)ptr4,讓其指向ptr1。FooPtrptr4=ptr1;//引用計(jì)數(shù)加1assert(ptr1==ptr2&&ptr4==ptr1);assert(ptr4.use_count==3&&ptr1.use_count==3&&ptr2.use_count()==3);11第十一頁(yè),共41頁(yè)。第六節(jié):shared_ptr的一個(gè)例子//現(xiàn)在我們轉(zhuǎn)移ptr2的所有權(quán)到另外一個(gè)新分配的名為Foo__2的Foo指針上去//在ptr2轉(zhuǎn)移所有權(quán)后,ptr2的計(jì)數(shù)器應(yīng)該是1&&ptr1和ptr4的計(jì)數(shù)器為2&&ptr1!=ptr2ptr2.reset(newFoo(“Foo2”);assert(ptr2.use_count()==1&&ptr1.use_count()==2&&ptr4.use_count()==2);assert(ptr1!=ptr2&&ptr1==ptr4);//前面ptr3因?yàn)楸籸eset()為0,并且get()=NULL了,我們?cè)儆胮tr5來(lái)指向ptr3,此時(shí)ptr5的引用計(jì)數(shù)也應(yīng)該//為0而不是加1,并且ptr5.get()返回值應(yīng)該也為NULLFooPtrptr5=ptr3;//引用計(jì)數(shù)為0assert(ptr5.use_count()==0&&ptr5.get()==NULL);//運(yùn)行到此時(shí),程序即將結(jié)束,在退出作用域前會(huì)調(diào)用析構(gòu)函數(shù)//首先會(huì)調(diào)用ptr2的析構(gòu)函數(shù),打印出DestructingaFoowithname=Foo__2//然后會(huì)調(diào)用ptr1和ptr4析構(gòu)函數(shù)進(jìn)行引用計(jì)數(shù)遞減//最終會(huì)打印出DestructingaFoowithname=Foo__1//這樣就沒(méi)有任何內(nèi)存泄露了哈哈哈哈}//結(jié)束test_boost_shared_ptr函數(shù)
12第十二頁(yè),共41頁(yè)。第七節(jié):shared_ptr使用注意點(diǎn)1、shared_ptr多次引用同一內(nèi)存數(shù)據(jù)導(dǎo)致程序崩潰
例如下面代碼會(huì)導(dǎo)致堆內(nèi)存破壞而引起程序奔潰voidtest_boost_shared_ptr_crash(){Foo*pFoo=newFoo("Foo1");boost::shared_ptr<Foo>ptr1(pFoo);boost::shared_ptr<Foo>ptr2(pFoo);}上述代碼兩次釋放同一內(nèi)存而破壞堆,導(dǎo)致程序奔潰。13第十三頁(yè),共41頁(yè)。第七節(jié):shared_ptr使用注意點(diǎn)1、shared_ptr多次引用同一內(nèi)存數(shù)據(jù)導(dǎo)致程序崩潰
解決方案: 1)直接使用boost::shared_ptr<int>ptr1(newint(100));使用匿名內(nèi)存分配限制其他shared_ptr多次指向同一內(nèi)存數(shù)據(jù)。多次指向時(shí)使用shared_ptr的賦值操作符或拷貝構(gòu)造函數(shù),例如shared_ptr<int>ptr2=ptr1。上面的匿名方式就是資源初始化既分配技術(shù),直接在構(gòu)造函數(shù)中分配內(nèi)存 2)使用boost的make_shared模板函數(shù),例如shared_ptr<int>ptr1=boost::make_shared<int>(100);shared_Ptr<int>ptr2=ptr1;
14第十四頁(yè),共41頁(yè)。第七節(jié):shared_ptr使用注意點(diǎn)2、shared_ptr循環(huán)引用導(dǎo)致內(nèi)存泄露,代碼如下:
classParent;classChild;classParent{public:~Parent(){std::cout<<“父類析構(gòu)函數(shù)被調(diào)用\n”;}public:boost::shared_ptr<Child>child_ptr;};15第十五頁(yè),共41頁(yè)。第七節(jié):shared_ptr使用注意點(diǎn)2、shared_ptr循環(huán)引用導(dǎo)致內(nèi)存泄露,代碼如下(續(xù)):classChild{public:~Child(){std::cout<<“子類析構(gòu)函數(shù)被調(diào)用\n”;}public:boost::shared_ptr<Parent>Parent_ptr;};
16第十六頁(yè),共41頁(yè)。第七節(jié):shared_ptr使用注意點(diǎn)2、shared_ptr循環(huán)引用導(dǎo)致內(nèi)存泄露,代碼如下(續(xù)):
intmain(){
boost::shared_ptr<Parent>father(newParent());//father引用計(jì)數(shù)為1
boost::shared_ptr<Child>son(newChild());//son引用計(jì)數(shù)為1
//
父子互相引用。
father->children=son;//son的引用計(jì)數(shù)為2
son->parent=father;//father的引用計(jì)數(shù)為2
return0;//退出作用域前,father和son的引用計(jì)數(shù)都減1,此時(shí)father和son的引用計(jì)數(shù)都是為1//因此各自指向的內(nèi)存無(wú)法釋放,導(dǎo)致內(nèi)存泄露}
17第十七頁(yè),共41頁(yè)。第七節(jié):shared_ptr使用注意點(diǎn)
2、shared_ptr循環(huán)引用導(dǎo)致內(nèi)存泄露上述代碼運(yùn)行后,不會(huì)調(diào)用father和son的析構(gòu)函數(shù),因?yàn)檠h(huán)引用,導(dǎo)致father和son的引用計(jì)數(shù)都為2,退出作用域時(shí)候,引用計(jì)數(shù)減1,因此father和son在退出作用域時(shí)候引用計(jì)數(shù)都為1,無(wú)法調(diào)用析構(gòu)函數(shù),于是造成father和son所指向的內(nèi)存得不到釋放,導(dǎo)致內(nèi)存泄露。
18第十八頁(yè),共41頁(yè)。第七節(jié):shared_ptr使用注意點(diǎn)2、shared_ptr循環(huán)引用導(dǎo)致內(nèi)存泄露的解決方案代碼:
針對(duì)循環(huán)引用,使用boost::weak_ptr可以很方便的解決該問(wèn)題。代碼如下:
classParent;classChild;classParent{public:~Parent(){std::cout<<“父類析構(gòu)函數(shù)被調(diào)用\n”;}public://boost::shared_ptr<Child>child_ptr;改為如下代碼:boost::weak_ptr<Child>child_ptr;};19第十九頁(yè),共41頁(yè)。第七節(jié):shared_ptr使用注意點(diǎn)2、shared_ptr循環(huán)引用導(dǎo)致內(nèi)存泄露的解決方案代碼:針對(duì)循環(huán)引用,使用boost::weak_ptr可以很方便的解決該問(wèn)題。代碼如下(續(xù)):classChild{public:~Child(){std::cout<<“子類析構(gòu)函數(shù)被調(diào)用\n”;}public://boost::shared_ptr<Parent>Parent_ptr;改為如下代碼:boost::weak_ptr<Parent>Parent_ptr;};
20第二十頁(yè),共41頁(yè)。第八節(jié):Boost::weak_ptr的介紹1、weak_ptr是用來(lái)解決循環(huán)引用和自引用對(duì)象
從前面的例子我們可以看出,引用計(jì)數(shù)是一種很便利的內(nèi)存管理機(jī)制,但是有一個(gè)很大的缺點(diǎn),那就是不能管理循環(huán)引用或自引用對(duì)象(例如鏈表或樹節(jié)點(diǎn)),為了解決這個(gè)限制,因此weak_ptr被引入到boost的智能指針庫(kù)中。2、weak_ptr并不能單獨(dú)存在
它是與shared_ptr同時(shí)使用的,它更像是shared_ptr的助手而不是智能指針,因?yàn)樗痪邆淦胀ㄖ羔樀男袨椋瑳](méi)有重載operator*和->操作符,這是特意的。這樣它就不能共享指針,不能操作資源,這正是它“弱”的原因。它最大的作用是協(xié)助shared_ptr工作,像旁觀者那樣觀察資源的使用情況。21第二十一頁(yè),共41頁(yè)。第八節(jié):Boost::weak_ptr的總結(jié)3、weak_ptr獲得資源的觀察權(quán)
weak_ptr可以從一個(gè)shared_ptr或另外一個(gè)weak_ptr構(gòu)造,從而獲得資源的觀察權(quán),但weak_ptr并沒(méi)有共享資源,它的構(gòu)造并不會(huì)引起引用計(jì)數(shù)的增加,同時(shí)它的析構(gòu)也不會(huì)引起引用計(jì)數(shù)的減少,它僅僅是觀察者。4、weak_ptr可以被用于標(biāo)準(zhǔn)容器庫(kù)中的元素
weak_ptr實(shí)現(xiàn)了拷貝構(gòu)造函數(shù)和重載了賦值操作符,因此weak_ptr可以被用于標(biāo)準(zhǔn)容器庫(kù)中的元素,例如:在一個(gè)樹節(jié)點(diǎn)中聲明子樹節(jié)點(diǎn)std::vector<boost::weak_ptr<Node>>children;22第二十二頁(yè),共41頁(yè)。第九節(jié):shared_ptr一些使用技巧:1、將shared_ptr用于標(biāo)準(zhǔn)容器庫(kù)有兩種方式:
1)將標(biāo)準(zhǔn)容器庫(kù)作為shared_ptr管理的對(duì)象 例如boost::shared_ptr<std::vector<T>>,使容器可以被安全的共享,用法與普通shared_ptr沒(méi)區(qū)別,我們不再討論。 2)將shared_ptr作為容器的元素 例如std::vector<boost::shared_ptr<T>>,因?yàn)閟hared_ptr支持拷貝構(gòu)造和賦值操作以及比較操作的語(yǔ)意,符合標(biāo)準(zhǔn)容器對(duì)元素的要求,所以可以在容器中安全的容納元素的指針而不是拷貝。標(biāo)準(zhǔn)容器可以容納原始指針,例如std::vector<T*>,但是這就喪失了容器的許多好處,因?yàn)闃?biāo)準(zhǔn)容器庫(kù)無(wú)法自動(dòng)管理類型為指針的元素,必須編寫額外的代碼來(lái)保證指針最終被正確的刪除,而保存shared_ptr作為標(biāo)準(zhǔn)容器庫(kù)的元素,既保證與存儲(chǔ)原始指針幾乎一樣的功能,而且不用擔(dān)心資源泄露。
23第二十三頁(yè),共41頁(yè)。第九節(jié):shared_ptr的使用技巧2、以函數(shù)方式封裝現(xiàn)有的c函數(shù)例如crt的FILE操作函數(shù),fopen/fclose/fread等函數(shù),我們可以使用一些技巧,利用shared_ptr進(jìn)行封裝,從而使我們不需要調(diào)用fclose,讓其自動(dòng)進(jìn)行內(nèi)存管理,代碼如下:1)實(shí)現(xiàn)函數(shù)(實(shí)際不需要實(shí)現(xiàn)該函數(shù),這里實(shí)現(xiàn)是為了在資源釋放時(shí)候打印出相關(guān)信息):typedefboost::shared_ptr<FILE>;void(FILE*f){fclose(f);std::cout<<“調(diào)用fclose函數(shù)釋放FILE資源\n”;}24第二十四頁(yè),共41頁(yè)。第九節(jié):shared_ptr使用技巧2、以函數(shù)方式封裝現(xiàn)有的c函數(shù)2)實(shí)現(xiàn)函數(shù)(constchar*path,constchar*mode){//fptr(fopen(path,mode),fclose);//直接使用fclose作為shared_ptr的刪除器fptr(fopen(path,mode),);//使用我們的包裝刪除器,在釋放資源時(shí)候打印出相關(guān)信息returnfptr;}25第二十五頁(yè),共41頁(yè)。第九節(jié):shared_ptr使用技巧3、用c++橋接設(shè)計(jì)模式來(lái)封裝現(xiàn)有的c函數(shù),隱藏實(shí)現(xiàn)細(xì)節(jié)
在c++的.h文件中聲明如下類:class{private:classimpl;//很重要一點(diǎn),前向申明實(shí)現(xiàn)類,具體實(shí)現(xiàn)在.cpp文件中,隱藏實(shí)現(xiàn)細(xì)節(jié) boost::shared_ptr<impl>pimpl;//shared_ptr作為私有成員變量public:(charconst*name,charconst*mode);voidRead(void*data,size_tsize);};26第二十六頁(yè),共41頁(yè)。第九節(jié):shared_ptr使用技巧:3、用c++橋接設(shè)計(jì)模式來(lái)封裝現(xiàn)有的c函數(shù)在c++的.cpp文件中實(shí)現(xiàn)如下類:class{private:impl(implconst&){}impl&operator=(implconst&){}FILE*f;public:impl(charconst*name,charconst*mode){f=fopen(name,mode);}~impl(){intresult=fclose(f);printf("invoke析構(gòu)函數(shù)result=%d\n",result);}voidread(void*data,size_tsize){fread(data,1,size,f)}};27第二十七頁(yè),共41頁(yè)。第九節(jié):shared_ptr使用技巧3、用c++橋接設(shè)計(jì)模式來(lái)封裝現(xiàn)有的c函數(shù)(constchar*name,constchar*mode):pimpl(new(name,mode)){}void(void*data,size_tsize){pimpl->read(data,size);}voidTest_CPP_(){ ptr(“memory.log”,“r”);//引用計(jì)數(shù)為1 ptr2=ptr;//引用計(jì)數(shù)為2 chardata[100]; ptr.Read(data,100); printf("%s\n",data);}//析構(gòu)ptr2引用計(jì)數(shù)為1,再析構(gòu)ptr,引用計(jì)數(shù)為0,釋放內(nèi)存,無(wú)泄漏28第二十八頁(yè),共41頁(yè)。第九節(jié):shared_ptr使用技巧4、使用面向接口編程方式隱藏實(shí)現(xiàn)
在c++的.h文件中聲明如下接口:classIPrinter{public:virtualvoidPrint()=0;protected://受保護(hù)的虛擬析構(gòu)函數(shù),導(dǎo)致本類必須被繼承,也不能調(diào)用delete操作符。virtual~IPrinter(){printf("invokeIPrintervirtual析構(gòu)函數(shù)\n");}};typedefboost::shared_ptr<IPrinter>PrinterPtr;PrinterPtrCreatePrinter();//工廠方法,創(chuàng)建IPrinter智能指針。29第二十九頁(yè),共41頁(yè)。第九節(jié):shared_ptr使用技巧4、使用面向接口編程方式隱藏實(shí)現(xiàn)在c++的.cpp文件中聲明如下實(shí)現(xiàn)類:(很重要一點(diǎn),實(shí)現(xiàn)類都是在cpp文件中的,必須要注意這一點(diǎn))classPrinter:publicIPrinter{private: FILE*f;public://使用createPrinter時(shí)候,調(diào)用實(shí)現(xiàn)類的構(gòu)造函數(shù),返回的是IPrinter的shared_ptr Printer(constchar*path,constchar*mode){f=fopen(path,mode); }//實(shí)現(xiàn)類的析構(gòu)是public,但是接口類的是protected,但是shared_ptr在析構(gòu)時(shí)候會(huì)自動(dòng)調(diào)用實(shí)現(xiàn)類的析構(gòu)//且再次調(diào)用基類受保護(hù)的虛擬析構(gòu)函數(shù)。通過(guò)這種機(jī)制我們可以完全封閉掉new和delete操作符,只能使用//公開的工廠方法函數(shù)返回接口智能指針,而且不需要也無(wú)法調(diào)用析構(gòu)函數(shù),完全由shared_ptr來(lái)管理內(nèi)存。//這樣我們?cè)谡麄€(gè)程序中都沒(méi)有原始指針的概念,從而不會(huì)忘記調(diào)用delte操作而導(dǎo)致內(nèi)存泄露。30第三十頁(yè),共41頁(yè)。第九節(jié):shared_ptr使用技巧4、使用面向接口編程方式隱藏實(shí)現(xiàn) ~Printer(){fclose(f);printf("invokePrinter析構(gòu)函數(shù)result=%d\n",result);} voidPrint(){chardata[100];fread(data,1,100,f);printf("%s\n",data);rewind(f);}};PrinterPtrCreatePrinter(){PrinterPtrptr(newPrinter("memory.log","r");returnptr};
31第三十一頁(yè),共41頁(yè)。第九節(jié):shared_ptr使用技巧5、使用shared_ptr持有一個(gè)具有侵入式的引用計(jì)數(shù)的對(duì)象如Com對(duì)象或intrusive_ptr等需要手動(dòng)增減引用計(jì)數(shù)的對(duì)象。假設(shè)我們要將shared_ptr用于一個(gè)COM對(duì)象。1)我們?cè)陬^文件中引入<boost/mem_fn.hpp>頭文件前定義宏:#defineBOOST_MEM_FN_ENABLE_STDCALL
2)#include<boost/mem_fn.hpp>3)我們定義一個(gè)函數(shù),例如shared_ptr<IWhatever>make_shared_from_COM(IWhatever*p)、{p->AddRef();//注意mem_fn仿函數(shù)的用法,它用于成員函數(shù),&類名::成員函數(shù)名shared_ptr<IWhatever>pw(p,mem_fn(&IWhatever::Release));returnpw;}一旦使用shared_ptr享有com的接口指針?biāo)袡?quán)后,com的引用計(jì)數(shù)被shared_ptr所接管,因此所有引用計(jì)數(shù)增減都是由shared_ptr來(lái)進(jìn)行.32第三十二頁(yè),共41頁(yè)。第九節(jié):shared_ptr一些使用技巧:6、使用shared_ptr持有一個(gè)win32handle例如win32使用HANDLE來(lái)代表內(nèi)核對(duì)象,所有內(nèi)核對(duì)象都使用CreateXXX創(chuàng)建一個(gè)句柄,而使用CloseHandle來(lái)釋放一個(gè)句柄。typedefvoid*HANDLE;//win32HANDLE的內(nèi)部定義,在windows中可以看到HANDLECreateMutex();BOOLCloseHandle(HANDLE);使用shared_ptr來(lái)管理上述類型的HANDLE,代碼如下:typedefshared_ptr<void>handle;33第三十三頁(yè),共41頁(yè)。第九節(jié):shared_ptr一些使用技巧:6、使用shared_ptr持有一個(gè)win32handleBOOLMyCloseHandleWrap(HANDLEh){std::cout<<“調(diào)用win32CloseHandleAPI\n”;returnCloseHandle(h);}handlecreateMutexHandle(){shared_ptr<void>ptr(CreateMutex(NULL,FALSE,NULL),MyCloseHandleWrap/*CloseHandle*/);}34第三十四頁(yè),共41頁(yè)。第九節(jié):shared_ptr使用技巧7、使用shared_ptr持有一個(gè)靜態(tài)分配的對(duì)象有時(shí)候我們需要使用shared_ptr來(lái)管理一個(gè)靜態(tài)分配的對(duì)象或全局對(duì)象,例如staticXxobj;由于靜態(tài)或全局對(duì)象的析構(gòu)是在程序結(jié)束時(shí)候自動(dòng)進(jìn)行的,我們不能夠在shared_ptr中自動(dòng)調(diào)用delete操作符,因此我們可以實(shí)現(xiàn)一個(gè)NULL析構(gòu)器來(lái)實(shí)現(xiàn)該目的
structnull_deleter//仿函數(shù)對(duì)象{//重載函數(shù)調(diào)用操作符()voidoperator()(void*const)const{}//沒(méi)有任何代碼};shared_ptr<X>CreateX(){shared_ptr<X>px(&xobj,null_deleter());returnpx;}
35第三十五頁(yè),共41頁(yè)。第九節(jié):shared_ptr使用技巧8、使用shared_ptr<void>持有任意對(duì)象的所有權(quán) 1)使用shared_ptr<void>來(lái)獲得任何對(duì)象的所有權(quán): 在該shared_ptr<void>離開作用域時(shí)候,會(huì)自動(dòng)調(diào)用該shared_ptr所享有的實(shí)際對(duì)象的析構(gòu)函數(shù), 2)如果要使用實(shí)際對(duì)象的相關(guān)成員函數(shù): 需要使用: boost::static_pointer_cast boost::dynamic_pointer_cast boost::const_pointer_cast boost::reinterpret_pointer_cast 這四個(gè)轉(zhuǎn)型模板函數(shù)。36第三十六頁(yè),共41頁(yè)。第九節(jié):shared
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 山東省章丘市2025年高三下第二次大考物理試題含解析
- 蘭州大學(xué)《供熱工程B》2023-2024學(xué)年第二學(xué)期期末試卷
- 吉林農(nóng)業(yè)大學(xué)《中醫(yī)診斷學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 中國(guó)地質(zhì)大學(xué)(武漢)《土木工程數(shù)值計(jì)算方法》2023-2024學(xué)年第一學(xué)期期末試卷
- 浙江省衢州市教聯(lián)盟體2024-2025學(xué)年初三2月命制英語(yǔ)試題含答案
- 中國(guó)音樂(lè)學(xué)院《大學(xué)數(shù)學(xué)(一)》2023-2024學(xué)年第一學(xué)期期末試卷
- 華北電力大學(xué)《幼兒心理與行為指導(dǎo)》2023-2024學(xué)年第二學(xué)期期末試卷
- 遼寧省盤錦市第二高級(jí)中學(xué)2025年高三年級(jí)第二學(xué)期調(diào)研考試物理試題試卷含解析
- 泉州輕工職業(yè)學(xué)院《國(guó)際公法》2023-2024學(xué)年第二學(xué)期期末試卷
- 日照市嵐山區(qū)2025屆小學(xué)六年級(jí)第二學(xué)期小升初數(shù)學(xué)試卷含解析
- 中國(guó)各地特色皮蛋
- 提高住院病歷完成及時(shí)性持續(xù)改進(jìn)(PDCA)
- 氣門搖臂軸支座的機(jī)械加工工藝及夾具設(shè)計(jì)畢業(yè)設(shè)計(jì)
- 企業(yè)職工代表任命協(xié)議書
- 山東司法警官職業(yè)學(xué)院教師招聘考試真題2022
- 地下管線測(cè)繪及數(shù)據(jù)處理
- 附件1:中國(guó)聯(lián)通動(dòng)環(huán)監(jiān)控系統(tǒng)B接口技術(shù)規(guī)范(V3.0)
- 衛(wèi)生院B超、心電圖室危急值報(bào)告制度及流程
- 醫(yī)療器械經(jīng)營(yíng)公司-年度培訓(xùn)計(jì)劃表
- 校園青年志愿者培訓(xùn)(服務(wù)禮儀講解)
- 教練員教學(xué)質(zhì)量信譽(yù)考核表
評(píng)論
0/150
提交評(píng)論