1.資源管理包括記憶體管理、檔案控制程式碼等等需要進行開啟(申請)、關閉(釋放)操作的過程
2.VS2010使用的C++規範,嚴格說來不是C++11,而是C++0x,但是一脈相承的
一:管理陣列
相較於auto_ptr,unique_ptr的增強點之一是支援對陣列物件指標的管理,比如:
struct A
{
int m_data;
A(int n=0){m_data =n;cout<<n<<" 被構造了"<<endl;}
~A(){cout<<m_data<<" 被銷燬了"<<endl;}
void Set(int n){m_data=n;
};
auto_ptr<A> p1(new A[5]);//由於自動釋放時,只呼叫delete,所以會導致A[0]以後物件的解構函式不會被呼叫。對於需要在解構函式中釋放資源的物件來說,是不能接受的。
unique_ptr<A[]> p2(new A[5]);//這樣,在釋放p2時,會使用delete [].
二:管理資源
在上一篇中,使用了sqlite:
sqlite3 *db = NULL;
//其他操作
sqlite3_close(db);
還有:
sqlite3_stmt *pstmt=NULL;
//其他操作
sqlite3_reset(pstmt);或者sqlite3_finalize(pstmt);
使用智慧指標或其他wrapper類管理資源,主要是
1.方便省事,最重要的是,避免資源洩露、未釋放
2.應對可能出現的異常.異常出現時,可以自動釋放資源,這就是所謂異常安全程式設計的三個條件之一(能釋放資源;能釋放資源且保證資源在異常前後狀態一致;不丟擲異常).另一方面,也可以使得程式碼美觀簡潔,否則為對付異常,不得不使用大堆大堆的if…else…
下面具體來看:
藉助於C++11(C++0x)新引入的auto、decltype、匿名函式物件(Lambda表示式)等特性,我們可以方便進行資源管理:
sqlite3 *pdb = NULL;
auto deleter = [](sqlite3 *pdb){sqlite3_close(pdb);}
int nRet = sqlite3_open16(L"F:\\my.db",&db);
std::unique_ptr<sqlite3,decltype(deleter)> pdb(pdb,deleter);
if(nRet)
{//失敗,但是這裡不用擔心資源管理了
}
else
{
}
//其他操作
//結束前,會動釋放資源
這樣,其他的各類資源:User物件HWND,GDI物件HBRUSH,Kernel物件HANDLE等,都可以用此方法進行資源管理,凡此種種,可以自由發揮。哈哈,媽媽再也不用擔心我申請資源不釋放了!
下一篇,也許可以談談藉助於11裡面的bind和function,利用stratgy模式,實現虛擬函式的效果。(Effective C++有個Item談到了這種方法)