1. 程式人生 > >effective c++乾貨之條款13:以物件管理資源

effective c++乾貨之條款13:以物件管理資源

對於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[]動作,所以指標指標如果指向一個數組那麼記憶體並不會被完全釋放。