【13】以物件管理資源

Andy Niu發表於2014-01-08

1、為什麼要以物件管理資源,它解決什麼問題?

  考慮下面的需求,客戶需要一個動態分配的資源。我提供一個工廠方法,返回一個指標,指向資源。那麼問題來了,誰來釋放資源呢?只有客戶知道什麼時候不再使用資源,因此,應該是客戶負責釋放資源。如果客戶沒有成功釋放資源,造成資源洩漏,注意,這裡洩漏的資源不光是一塊記憶體,還可能包括這塊記憶體儲存的其他資源。把成功釋放資源的希望,寄託在客戶身上,顯然是不靠譜的。因為:a、客戶可能忘記delete;b、程式碼異常,導致沒有執行到delete。

2、它是如何解決這個問題的?

  我們知道,棧上分配的物件有個特點,超出作用域,不管什麼情況,都會自動呼叫析構方法。因此,可以把堆上獲取的資源,放入棧上的物件中,棧上物件的析構方法,進行delete操作,釋放資源。相當於對獲取的指標,進行封裝。

3、以物件管理資源有兩個關鍵想法:

  a、獲取資源後,立刻放入棧上的管理物件內,也就是RAII(Resource Acquisition Is Initialization);

  b、棧上的管理物件超出作用域,無論出現什麼情況,必定呼叫析構方法,釋放資源。

4、這個管理物件類似指標,叫做智慧指標。有兩個典型的智慧指標:auto_ptr和shared_ptr。auto_ptr會導致擁有權的轉移,shared_ptr可以共享一個資源。

5、需要注意:auto_ptr和shared_ptr,在析構方法中,執行的是delete,而不是delete[]。這意味著,千萬不要使用auto_ptr和shared_ptr管理動態分配的陣列。

6、再仔細考慮下開頭提出的需求,返回一個資源,期望客戶進行封裝,那還不如我自己封裝好,返回給客戶呢。我返回一個管理物件,用它初始化客戶端的一個管理物件,注意:客戶端的管理物件,只是一個副本。但是,他們中的指標都指向同一塊記憶體。而且,管理物件之間的copy構造成本很低,就是儲存同一個指標值,指向同一塊記憶體。

相關文章