激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C/C++ - C++中auto_ptr智能指針的用法詳解

C++中auto_ptr智能指針的用法詳解

2021-04-09 13:50MONKEY_D_MENG C/C++

這篇文章主要介紹了C++中auto_ptr智能指針的用法詳解的相關(guān)資料,需要的朋友可以參考下

智能指針(auto_ptr) 這個(gè)名字聽起來很酷是不是?其實(shí)auto_ptr 只是C++標(biāo)準(zhǔn)庫提供的一個(gè)類模板,它與傳統(tǒng)的new/delete控制內(nèi)存相比有一定優(yōu)勢,但也有其局限。本文總結(jié)的8個(gè)問題足以涵蓋auto_ptr的大部分內(nèi)容。

auto_ptr是什么?

auto_ptr 是C++標(biāo)準(zhǔn)庫提供的類模板,auto_ptr對象通過初始化指向由new創(chuàng)建的動(dòng)態(tài)內(nèi)存,它是這塊內(nèi)存的擁有者,一塊內(nèi)存不能同時(shí)被分給兩個(gè)擁有者。當(dāng)auto_ptr對象生命周期結(jié)束時(shí),其析構(gòu)函數(shù)會(huì)將auto_ptr對象擁有的動(dòng)態(tài)內(nèi)存自動(dòng)釋放。即使發(fā)生異常,通過異常的棧展開過程也能將動(dòng)態(tài)內(nèi)存釋放。auto_ptr不支持new 數(shù)組。

C++中指針申請和釋放內(nèi)存通常采用的方式是new和delete。然而標(biāo)準(zhǔn)C++中還有一個(gè)強(qiáng)大的模版類就是auto_ptr,它可以在你不用的時(shí)候自動(dòng)幫你釋放內(nèi)存。下面簡單說一下用法。

?
1
<textarea cols="50" rows="15" name="code" class="cpp">

用法一: std::auto_ptr&lt;MyClass&gt;m_example(new MyClass());

用法二: std::auto_ptr&lt;MyClass&gt;m_example; m_example.reset(new MyClass());

用法三(指針的賦值操作): std::auto_ptr&lt;MyClass&gt;m_example1(new MyClass());

std::auto_ptr&lt;MyClass&gt;m_example2(new MyClass()); m_example2=m_example1;</textarea>

則C++會(huì)把m_example所指向的內(nèi)存回收,使m_example1 的值為NULL,所以在C++中,應(yīng)絕對避免把a(bǔ)uto_ptr放到容器中。即應(yīng)避免下列代碼:

vector<auto_ptr<MyClass>>m_example;

當(dāng)用算法對容器操作的時(shí)候,你很難避免STL內(nèi)部對容器中的元素實(shí)現(xiàn)賦值傳遞,這樣便會(huì)使容器中多個(gè)元素被置位NULL,而這不是我們想看到的。

雖然,標(biāo)準(zhǔn)auto_ptr智能指針機(jī)制很多人都知道,但很少使用它。這真是個(gè)遺憾,因?yàn)閍uto_ptr優(yōu)雅地解決了C++設(shè)計(jì)和編碼中常見的問題,正確地使用它可以生成健壯的代碼。本文闡述了如何正確運(yùn)用auto_ptr來讓你的代碼更加安全——以及如何避免對auto_ptr危險(xiǎn)但常見的誤用,這些誤用會(huì)引發(fā)間斷性發(fā)作、難以診斷的bug。

為什么稱它為“自動(dòng)”指針?auto_ptr只是眾多可能的智能指針之一。許多商業(yè)庫提供了更復(fù)雜的智能指針,用途廣泛而令人驚異,從管理引用的數(shù)量到提供先進(jìn)的代理服務(wù)。可以把標(biāo)準(zhǔn)C++ auto_ptr看作智能指針的Ford Escort(elmar注:可能指福特的一種適合家居的車型):一個(gè)簡易、通用的智能指針,它不包含所有的小技巧,不像專用的或高性能的智能指針那么奢華,但是它可以很好的完成許多普遍的工作,它很適合日常性的使用。

auto_ptr所做的事情,就是動(dòng)態(tài)分配對象以及當(dāng)對象不再需要時(shí)自動(dòng)執(zhí)行清理。這里是一個(gè)簡單的代碼示例,沒有使用auto_ptr所以不安全:

?
1
<textarea cols="50" rows="15" name="code" class="cpp">// 示例1(a):原始代碼 void f() { T* pt( new T ); /*...更多的代碼...*/ delete pt; }</textarea>

我們大多數(shù)人每天寫類似的代碼。如果f()函數(shù)只有三行并且不會(huì)有任何意外,這么做可能挺好的。但是如果f()從不執(zhí)行delete語句,或者是由于過早的返回,或者是由于執(zhí)行函數(shù)體時(shí)拋出了異常,那么這個(gè)被分配的對象就沒有被刪除,從而我們產(chǎn)生了一個(gè)經(jīng)典的內(nèi)存泄漏。

能讓示例1(a)安全的簡單辦法是把指針封裝在一個(gè)“智能的”類似于指針的對象里,這個(gè)對象擁有這個(gè)指針并且能在析構(gòu)時(shí)自動(dòng)刪除這個(gè)指針?biāo)傅膶ο蟆R驗(yàn)檫@個(gè)智能指針可以簡單的當(dāng)成一個(gè)自動(dòng)的對象(這就是說,它出了作用域時(shí)會(huì)自動(dòng)毀滅),所以很自然的把它稱之為“智能”指針:

?
1
2
<textarea cols="50" rows="15" name="code" class="cpp">//
示例1(b):安全代碼,使用了auto_ptr void f() { auto_ptr&lt;T&gt; pt( new T ); /*...更多的代碼...*/ } // 酷:當(dāng)pt出了作用域時(shí)析構(gòu)函數(shù)被調(diào)用,從而對象被自動(dòng)刪除</textarea>

現(xiàn)在代碼不會(huì)泄漏T類型的對象,不管這個(gè)函數(shù)是正常退出還是拋出了異常,因?yàn)閜t的析構(gòu)函數(shù)總是會(huì)在出棧時(shí)被調(diào)用,清理會(huì)自動(dòng)進(jìn)行。

最后,使用一個(gè)auto_ptr就像使用一個(gè)內(nèi)建的指針一樣容易,而且如果想要“撤銷”資源,重新采用手動(dòng)的所有權(quán),我們只要調(diào)用release()。

?
1
<textarea cols="50" rows="15" name="code" class="cpp">// 示例2:使用一個(gè)auto_ptr void g() { // 現(xiàn)在,我們有了一個(gè)分配好的對象 T* pt1 = new T; // 將所有權(quán)傳給了一個(gè)auto_ptr對象 auto_ptr&lt;T&gt; pt2(pt1); // 使用auto_ptr就像我們以前使用簡單指針一樣, *pt2 = 12; // 就像*pt1 = 12 pt2-&gt;SomeFunc(); // 就像pt1-&gt;SomeFunc(); // 用get()來獲得指針的值 assert( pt1 == pt2.get() ); // 用release()來撤銷所有權(quán) T* pt3 = pt2.release(); // 自己刪除這個(gè)對象,因?yàn)楝F(xiàn)在沒有任何auto_ptr擁有這個(gè)對象 delete pt3; } // pt2不再擁有任何指針,所以不要試圖刪除它...OK,不要重復(fù)刪除 </textarea>

最后,我們可以使用auto_ptr的reset()函數(shù)來重置auto_ptr使之擁有另一個(gè)對象。如果這個(gè)auto_ptr已經(jīng)擁有了一個(gè)對象,那么,它會(huì)先刪除已經(jīng)擁有的對象,因此調(diào)用reset()就如同銷毀這個(gè)auto_ptr,然后新建一個(gè)并擁有一個(gè)新對象:

 

?
1
2
<textarea cols="50" rows="15" name="code" class="cpp">//
示例 3:使用reset() void h() { auto_ptr&lt;T&gt; pt( new T(1) ); pt.reset( new T(2) ); // 刪除由"new T(1)"分配出來的第一個(gè)T } // 最后pt出了作用域,第二個(gè)T也被刪除了</textarea>

auto_ptr用法:

1. 需要包含頭文件<memory>。

2. Constructor:explicit auto_ptr(X* p = 0) throw(); 將指針p交給auto_ptr對象托管。

3. Copy constructor:auto_ptr(const auto_ptr&) throw(); template<class Y> auto_ptr(const auto_ptr<Y>& a) throw(); 指針的托管權(quán)會(huì)發(fā)生轉(zhuǎn)移。

4. Destructor: ~auto_ptr(); 釋放指針p指向的空間。

5. 提供了兩個(gè)成員函數(shù) X* get() const throw(); //返回保存的指針

6. 對象中仍保留指針 X* release() const throw(); //返回保存的指針,對象中不保留指針

auto_ptr實(shí)現(xiàn)關(guān)鍵點(diǎn):

1. 利用特點(diǎn)“棧上對象在離開作用范圍時(shí)會(huì)自動(dòng)析構(gòu)”。

2. 對于動(dòng)態(tài)分配的內(nèi)存,其作用范圍是程序員手動(dòng)控制的,這給程序員帶來了方便但也不可避免疏忽造成的內(nèi)存泄漏,畢竟只有編譯器是最可靠的。
3. auto_ptr通過在棧上構(gòu)建一個(gè)對象a,對象a中wrap了動(dòng)態(tài)分配內(nèi)存的指針p,所有對指針p的操作都轉(zhuǎn)為對對象a的操作。而在a的析構(gòu)函數(shù)中會(huì)自動(dòng)釋放p的空間,而該析構(gòu)函數(shù)是編譯器自動(dòng)調(diào)用的,無需程序員操心。

多說無益,看一個(gè)最實(shí)用的例子:

?
1
2
3
<textarea cols="50" rows="15" name="code" class="cpp">#include &lt;iostream&gt; #include &lt;memory&gt; using namespace std; class TC { public: TC(){cout&lt;&lt;"TC()"&lt;&lt;endl;} ~TC(){cout&lt;&lt;"~TC()"&lt;&lt;endl;} }; void foo(bool isThrow) { auto_ptr&lt;TC&gt; pTC(new TC);
// 方法2 //TC *pTC = new TC;
// 方法1 try { if(isThrow) throw "haha"; } catch(const char* e) { //delete pTC; // 方法1 throw; } //delete pTC; // 方法1 } int main() { try { foo(true); } catch(...) { cout&lt;&lt;"caught"&lt;&lt;endl; } system("pause"); }</textarea>

1. 如果采用方案1,那么必須考慮到函數(shù)在因throw異常的時(shí)候釋放所分配的內(nèi)存,這樣造成的結(jié)果是在每個(gè)分支處都要很小心的手動(dòng) delete pTC;。

2. 如果采用方案2,那就無需操心何時(shí)釋放內(nèi)存,不管foo()因何原因退出, 棧上對象pTC的析構(gòu)函數(shù)都將調(diào)用,因此托管在之中的指針?biāo)傅膬?nèi)存必然安全釋放。
至此,智能指針的優(yōu)點(diǎn)已經(jīng)很明了了。

但是要注意使用中的一個(gè)陷阱,那就是指針的托管權(quán)是會(huì)轉(zhuǎn)移的。 例如在上例中,如果 auto_ptr<TC> pTC(new TC); auto_ptr<TC> pTC1=pTC; 那么,pTC1將擁有該指針,而pTC沒有了,如果再用pTC去引用,必然導(dǎo)致內(nèi)存錯(cuò)誤。

要避免這個(gè)問題,可以考慮使用采用了引用計(jì)數(shù)的智能指針,例如boost::shared_ptr等。auto_ptr不會(huì)降低程序的效率,但auto_ptr不適用于數(shù)組,auto_ptr根本不可以大規(guī)模使用。 shared_ptr也要配合weaked_ptr,否則會(huì)很容易觸發(fā)循環(huán)引用而永遠(yuǎn)無法回收內(nèi)存。 理論上,合理使用容器加智能指針,C++可以完全避免內(nèi)存泄露,效率只有微不足道的下降(中型以上程序最多百分之一)。

以上所述是小編給大家介紹的C++中auto_ptr智能指針的用法詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對服務(wù)器之家網(wǎng)站的支持!

原文鏈接:http://blog.csdn.net/monkey_d_meng/article/details/5901392

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 精品av在线播放 | 亚洲第一视频 | 久草手机在线观看视频 | 精品久久久一二三区播放播放播放视频 | 国产精品成人久久久久a级 男女无遮挡羞羞视频 | av电影网站在线观看 | 亚洲国产精品一区 | 美国黄色毛片女人性生活片 | 欧美老逼 | 一区二区免费 | 操操操日日日干干干 | 黄色av片三级三级三级免费看 | 久久综合一区 | 国产一区二区久久精品 | 欧美老外a级毛片 | 久久久精品视频免费 | 国产资源视频在线观看 | 美女网站色免费 | www日韩大片 | 久久av免费 | 国产精品999在线观看 | 一级毛片在线观看免费 | av在线中文 | 草草免费视频 | 久久精品a一级国产免视看成人 | 免费国产成人高清在线看软件 | 精品国产一区二区在线 | 毛片免费视频网站 | 成人免费一区二区三区在线观看 | 国产精品99爱 | 色婷婷久久久久久 | 男女污污视频网站 | 1314成人网| 精品国产看高清国产毛片 | 91看片在线观看视频 | 久久蜜桃精品一区二区三区综合网 | 国产午夜精品一区二区三区不卡 | 欧美日韩亚洲不卡 | 欧美一级毛片欧美一级成人毛片 | 视频一区国产 | 香蕉成人在线视频 |