effective c++乾貨之條款13:以物件管理資源
阿新 • • 發佈:2018-12-16
對於c++來說,一般所指的資源就是動態分配的記憶體,其實資源還包括互斥鎖,網路套接字等。
如果我們定義了一個物件:
class Bird
{
//...
};
在一個函式中,如果我們new了一個Brid物件:
void Fun()
{
Bird *bird = new Bird;
//...
delete bird;
}
即使我們記得在最後添加了delete,但隨著程式碼被一次次地,不同的人來維護,delete就有可能執行不到。例如在delete前的語句中添加了return,或者在...期間丟擲了異常,都有可能導致delete最後執行不到,那麼就會導致記憶體洩漏。
解決辦法:
使用智慧指標
1. auto_ptr智慧指標
標準程式庫中的auto_ptr(是一個類)是一個智慧指標,它的解構函式將自動對所指的物件呼叫delete。
void Fun()
{
std::auto_ptr<Bird> pBird(new Bird);
//...
}
這樣,當作用域結束,auto_ptr會自動呼叫釋放動態分配的記憶體。
auto_ptr有一個不同尋常的屬性:如果利用拷貝構造或者copy assignment操作符複製它們,那麼被複制的指標將變成null,即不允許兩個智慧指標指向相同位置。
void Fun() { std::auto_ptr<Bird> pBird1(new Bird); std::auto_ptr<Bird> pBird2(pBird1); //... }
此時,pBird1將指向null,而pBird2取而代之。
2. 計數型智慧指標
為了能使兩個指標指向同一位置,我們可以使用另外一種智慧指標:
void Fun()
{
std::trl::shared_ptr<Bird> pBird1(new Bird);
std::trl::shared_ptr<Bird> pBird2(pBird1);//指向相同位置
pBird2 = pBird1; //同上
//...
}
這樣,在作用域結束後,指標所指的物件會被自動銷燬。
3. 注意
在智慧指標的解構函式中,呼叫的是delete而不是delete[]動作,所以指標指標如果指向一個數組那麼記憶體並不會被完全釋放。