條款14 在資源管理類中小心copying行為

2021-06-29 01:56:47 字數 1788 閱讀 8811

總結:

條款13介紹了作為資源管理類支柱的 resource acquisition isinitialization (raii) 原則,並描述了 auto_ptr 和 tr1::shared_ptr 在基於堆的資源上運用這一原則的表現。然而,並非所有的資源都是基於堆的,對於這樣的資源,像 auto_ptr 和 tr1::shared_ptr 這樣的智慧型指標往往不適合作為資源掌管者。在這種情況下,有時可能要根據你自己的需要去建立自己的資源管理類。

例如,假設使用 c api 提供的 lock 和 unlock 函式去操縱 mutex 型別的互斥物件:

void lock(mutex *pm); // 鎖定pm所指的互斥器

void unlock(mutex *pm); // 將互斥器解除鎖定

為了確保不會忘記解鎖乙個被你加了鎖的 mutex,你希望建立乙個類來管理鎖。raii 原則規定了這樣乙個類的基本結構,也就是「資源在構造期間獲得,在析構期間釋放」:

class lock // 獲得資源

~lock() // 釋放資源

private:

mutex *mutexptr;

};客戶對lock的用法符合raii方式:

mutex m; // 定義互斥器

... // 在區塊最末尾,自動解除互斥器鎖定

critical section:每個執行緒中訪問臨界資源的那段程式稱為臨界區(critical section)(臨界資源是一次僅允許乙個執行緒使用的共享資源)。每次只准許乙個執行緒進入臨界區,進入後不允許其他執行緒進入。不論是硬體臨界資源,還是軟體臨界資源,多個執行緒必須互斥地對它進行訪問。

這沒什麼問題,但是如果乙個 lock 物件被拷貝應該發生什麼?

lock ml1(&m); // 鎖定m

lock ml2(ml1); // 將ml1複製到ml2身上,這會發生什麼?

當乙個 raii 物件被拷貝的時候應該發生什麼?大多數情況下,你可以從下面各種可能性中挑選乙個:

class lock: private uncopyable ;

通常,raii 類只需要包含乙個 tr1::shared_ptr 資料成員就能夠實現引用計數的拷貝行為。例如lock 要使用引用計數,他可能要將 mutexptr 的型別從 mutex* 改變為 tr1::shared_ptr。然而tr1::shared_ptr 的預設行為是當引用計數變為 0 的時候將它刪除,但這不是我們要的,我們想要將它解鎖,而不是刪除。

幸運的是,tr1::shared_ptr 允許指定所謂的"deleter"(刪除器)——當引用計數變為 0 時呼叫的乙個函式或者函式物件(這一功能是 auto_ptr 所沒有的,auto_ptr 總是刪除它的指標)。deleter是 tr1::shared_ptr 的建構函式可有可無的第二引數,所以,**看起來就像這樣:

class lock

private:

std::tr1::shared_ptrmutexptr; };

// 使用shared_ptr替換raw pointer

注意 lock 類沒有宣告析構函式。類的析構函式(無論它是編譯器生成還是使用者定義)會自動呼叫這個類的non-static成員變數的析構函式(本例為mutexptr)。當互斥體的引用計數變為 0 時,mutexptr 的析構函式會自動呼叫tr1::shared_ptr 的deleter(本例為unlock)。

某些標準字串型別是由「指向heap記憶體」的指標構成,那記憶體用來存放字串的組成字元。這樣的字串物件包含乙個指標指向一塊heap記憶體。當乙個string 物件被拷貝,這個副本應該由那個指標和它所指向的記憶體組成。這樣的字串展現深度複製行為。

條款14 在資源管理類中小心copying行為

結論1 複製raii物件必須一併複製它所管理的資源,所以資源的copying行為決定raii物件的copying行為。結論2 普遍而常見的raii class copying行為是 1 抑制copying,即禁止複製 很多時候允許raii物件被複製是不合理的。2 對底層資源施行引用計數法 在此情況下...

條款14 在資源管理類中小心copying行為

條款14 在資源管理類中小心copy行為 1.複製raii物件必須一併複製它所管理的資源,所以資源的copying行為決定raii物件的copying行為。2.普遍而常見的raii class copying行為是 抑制copying 施行引用計數法 reference counting 不過其他行...

條款14 在資源管理類中小心copying行為

raii物件被複製時的幾種選擇 前兩種最常用 禁止複製 class a private uncopyable 引用計數,複製時將資源的 被引用數 遞增。raiiclass包含乙個shared ptr成員變數即可。shared ptr可以定製刪除器,即當引用為0時觸發。class lock 不必宣告析...