在c++程式執行的過程中免不了要進行資源的分配——尤其是在遊戲中!資源可以有很多種 —— 貼圖、音訊、shader到控制代碼、字串這些東西都可以被稱為資源。資源的管理是專案中很重要的一輪,做得不好的話輕則記憶體洩漏、重則記憶體崩潰。
而raii則是在c++專案中用於資源管理的一種重要的程式設計思想。
c++中不可或缺的東西就是class,而每個class不可或缺的就是建構函式和析構函式。前者用於物件被構造時進行的一系列操作,後者用於物件被析構時所執行的函式。
而值得一提的是,在c++中,如果乙個類被宣告在棧空間,則在該函式執行完畢從棧空間彈出之後,類會自動呼叫析構函式。可是如果被顯示宣告在堆空間(使用new方法或者malloc方法),則需要顯式呼叫析構函式才能進行析構。
raii表示的是「資源獲取即初始化」(resource aquisition is initialization),而不是某些人認為的「初始化即資源獲取」(initialization is resource acquisition)。
raii的技術很簡單,利用c++物件生命週期的概念來控制程式的資源。它的技術原理很簡單,如果希望對某個重要資源進行跟蹤,那麼建立乙個物件,並將資源的生命週期和物件的生命週期相關聯。這樣一來c++自帶的物件管理設施就可以來管理資源了。
最簡單的形式:建立乙個物件,讓她的建構函式獲取乙份資源,而析構函式則釋放這個資源:
class resource;
class resourcehandle
// release resource
~resourcehandle()
// get access to resource
resource *get()
private:
// make sure it can not be copied by others
resourcehandle (const resourcehandle &);
resourcehandle & operator = (const resourcehandle &);
resource *r_;
};
resourcehandle物件的最好的地方就是:如果它被宣告為乙個函式的區域性變數,或者作為乙個引數,或者靜態變數,我們都可以保證析構函式得到呼叫了。這樣一來就可以釋放物件所引用的資源。
再看看乙個反例:
void f()
就如同注釋所講,可能一開始的時候上面那段**是安全的,rh的資源總是可以被釋放。
但是如果這段**經歷了一些維護呢?比如說上面的g()函式,有可能會造成函式的提前返回,所以就有可能執行不到最後一句釋放資源的**了,因此這段**是危險的。
那麼該如何使用raii程式設計思想對這段**進行改進呢?**如下:
void f()
這樣一來raii就使得**就更加健壯了,因為只要是函式返回了,無論是通過何種途徑,那麼在返回的時候析構函式就會自動釋放資源。
使用raii只有一種情況無法保證析構函式得到呼叫,就是當resourcehandle
被動態分配到堆空間上了,這樣一來就只能顯示得呼叫delete resourcehandle
物件才能保證資源釋放了,比如下面的**:
resourcehandle *rhp = new resourcehandle(new resource);
那麼此時的問題在於,因為動態分配的東西需要顯示呼叫delete
才能釋放,所以上面的做法通常是危險的做法。安全的做法是將raii的handle分配到棧空間去,此時就能夠保證記憶體的釋放。
《全文完》
程式設計思想
pop面向過程的程式設計思想把電腦程式看作是一組命令的集合,即一組函式的順序執行。面向過程設計時,將整個程式切分成幾個函式模組,每乙個模組負責解決乙個問題。oop把物件作為程式的基本單元,乙個物件包含了資料和運算元據的方法 method 物件導向的程式設計把電腦程式視為一組物件的集合,每個物件都可以...
traits程式設計思想
首先引用書上的一句話 stl中心思想是把資料容器和演算法分開。迭代器是兩者結合的關鍵,那麼我們演算法當然是通過迭代器來對容器操作了,但是我們在演算法中經常需要得到迭代器的相應型別 比如 迭代器說指向的型別。那麼怎麼得到這些型別呢,當然你可以通過函式模板實現部分功能,也可以通過在迭代器裡自定義這些型別...
AOP程式設計思想
面向切面程式設計 這是最近接觸到的思想。看名字感覺很新奇,其實就是在底層實現攔截呼叫。通俗點,如果你不小心踩到狗屎,心理不平衡時,你可以在人人都會走過的路上放一坨狗屎,這樣,路過的人都會踩到狗屎。這樣你就實現了面向切面程式設計 個人理解 關鍵字 切面,攔截。用途 操作日誌,許可權驗證等。老規矩介面先...