官术网_书友最值得收藏!

3.1 smart_ptr庫概述

計算機系統中有很多種資源,內存是我們最常用到的資源,此外還有文件描述符、socket、操作系統handle、數據庫連接等,在程序中,申請這些資源后必須及時歸還,否則會產生難以預料的后果。

3.1.1 RAII機制

為了管理內存等資源,C++程序員通常采用RAII機制(Resource Acquisition Is Initialization,資源獲取即初始化),在類的構造函數里申請資源,然后使用資源,最終在析構函數中釋放資源。

如果對象是用聲明的方式在棧上創建的(一個局部對象),那么RAII機制會正常工作,當離開作用域時,該對象會自動銷毀,從而調用析構函數釋放資源。

但如果對象是用new操作符在堆上創建的,那么它的析構函數將無法自動調用,程序員必須明確地用對應的delete操作符銷毀它,才能釋放資源,這就存在著資源泄漏的隱患,因為這時沒有任何對象對已經獲取的資源負責,如果因某些意外導致程序未能執行delete語句,那么內存等資源就會永久丟失。例如:

new、delete及指針的不恰當運用是C++語言中造成資源獲取、釋放問題的根源,能否正確地運用delete是區分C++語言新手與熟手的關鍵。但很多人——即使是熟練的C++程序員,也經常會忘記調用delete。

3.1.2 智能指針

智能指針(smart pointer)是C++群體中熱門的議題,圍繞它有很多有價值的討論和結論。它實踐了推薦書目[1]中講解的代理模式,代理了原始“裸”指針的行為,為它添加了更多有用的特性。

向C++引入異常機制后,智能指針由一種技巧升級為一種非常重要的技術,因為如果沒有智能指針,程序員必須保證new對象能在正確的時機delete,必須到處編寫異常捕獲代碼以釋放資源,而智能指針則可以在退出作用域時(無論是因正常流程離開還是因異常離開)總調用delete來析構在堆上動態分配的對象。

存在很多種智能指針,其中最早的一個應該是C++98標準中的自動指針auto_ptr,它解決了自動釋放獲取資源的部分問題,例如std::auto_ptr已經在C++標準中被聲明為廢棄,現在應該使用新的智能指針std::unique_ptr,故本書中不再講述auto_ptr相關的內容。

auto_ptr的構造函數可以接收new操作符或對象工廠創建出的對象指針作為參數,從而代理原始指針。雖然它是一個對象,但因為重載了operator*和opreator->,其行為非常類似指針,可以把它用在大多數普通指針可用的地方。當退出作用域時(離開函數main或發生異常),C++語言會保證銷毀auto_ptr對象,調用auto_ptr的析構函數,進而使用delete操作符刪除原始指針,釋放資源。

auto_ptr很好用,由于它被包含在C++標準庫中,所以可以在世界范圍內被廣泛使用,這使智能指針的思想和用法深入人心。但auto_ptr存在一些缺陷,所以新的C++標準提供了更完善的unique_ptr、shared_ptr和weak_ptr,而它們正是基于我們接下來要介紹的boost.smart_ptr庫的。

boost.smart_ptr庫提供了很多種智能指針,常用的有scoped_ptr、shared_ptr、weak_ptr和intrusive_ptr。它們是輕量級的對象,其速度與原始指針相差無幾,都是異常安全的(exception safe),而且對于所指向的類型T也僅有一個很小且很合理的要求:類型T的析構函數不能拋出異常。

這些智能指針都位于名字空間boost,需要包含的頭文件如下:

主站蜘蛛池模板: 和田市| 吕梁市| 昌江| 南投县| 卫辉市| 巴东县| 怀来县| 新泰市| 宣汉县| 财经| 荆门市| 平凉市| 高淳县| 普洱| 柳州市| 紫阳县| 黑水县| 麦盖提县| 馆陶县| 会宁县| 互助| 西充县| 涡阳县| 绥滨县| 中江县| 云霄县| 洛南县| 绥江县| 民乐县| 黄龙县| 青神县| 宣武区| 河津市| 泰宁县| 宜兰市| 哈密市| 昌邑市| 毕节市| 盖州市| 元阳县| 南丹县|