auto_ptr 淺析(轉)

auto_ptr是C++標準庫中(<utility>)爲了解決資源泄漏的問題提供的一個智能指針類模板(注意:這只是一種簡單的智能指針)

auto_ptr的實現原理其實就是RAII,在構造的時候獲取資源,在析構的時候釋放資源,並進行相關指針操作的重載,使用起來就像普通的指針。

std::auto_ptr<ClassA> pa(new ClassA);

下面主要分析一下auto_ptr的幾個要注意的地方:

1,Transfer of Ownership

auto_ptr與boost庫中的share_ptr不同的,auto_ptr沒有考慮引用計數,因此一個對象只能由一個auto_ptr所擁有,在給其他auto_ptr賦值的時候,會轉移這種擁有關係。

#include <utility>
#include <iostream>
using namespace std;
 
class A
{
public:
    A() { id = ++count; cout << "create A" << id  <<  "\n"; }
    ~A() { cout << "destroy A" << id << "\n"; }
private:
    static int count;
    int id;
};
 
int A::count = 0;
 
/*調用該函數會丟失掉所有權*/
void sink(auto_ptr<A> a)
{
    cout << "Enter sink()\n";
}
 
/*調用該函數會創建對象,並獲取所有權*/
auto_ptr<A> create()
{
    cout << "Enter create()\n";
    auto_ptr<A> a(new A());
    return a;
}
 
int main(int argc, char *argv[])
{
    auto_ptr<A> a1 = create();
    auto_ptr<A> a2 = a1; /*轉移所有權,此時a1無效了*/
    auto_ptr<A> a3(new A());
    cout << "Exit create()\n";
    sink(a2);/*丟失所有權,會發現a2的釋放在sink函數中進行*/
    cout << "Exit sink()\n";
    return 0;
}
 
輸出結果是:<br>Enter create()<br>create A1<br>create A2<br>Exit create()<br>Enter sink()<br>destroy A1<br>Exit sink()<br>destroy A2<br><br>

2,從上可知由於在賦值,參數傳遞的時候會轉移所有權,因此不要輕易進行此類操作。

   比如:std::auto_ptr<ClassA> pa(new ClassA());

   bad_print(pa); //丟失了所有權

   pa->...; //Error

3,使用auto_ptr作爲成員變量,以避免資源泄漏。

   爲了防止資源泄漏,我們通常在構造函數中申請,析構函數中釋放,但是隻有構造函數調用成功,析構函數纔會被調用,換句話說,如果在構造函數中產生了異常,那麼析構函數將不會調用,這樣就會造成資源泄漏的隱患。

   比如,如果該類有2個成員變量,指向兩個資源,在構造函數中申請資源A成功,但申請資源B失敗,則構造函數失敗,那麼析構函數不會被調用,那麼資源A則泄漏。

  爲了解決這個問題,我們可以利用auto_ptr取代普通指針作爲成員變量,這樣首先調用成功的成員變量的構造函數肯定會調用其析構函數,那麼就可以避免資源泄漏問題。

4,不要誤用auto_ptr

  1)auto_ptr不能共享所有權,即不要讓兩個auto_ptr指向同一個對象。

  2)auto_ptr不能指向數組,因爲auto_ptr在析構的時候只是調用delete,而數組應該要調用delete[]。

  3)auto_ptr只是一種簡單的智能指針,如有特殊需求,需要使用其他智能指針,比如share_ptr。

  4)auto_ptr不能作爲容器對象,STL容器中的元素經常要支持拷貝,賦值等操作,在這過程中auto_ptr會傳遞所有權,那麼source與sink元素之間就不等價了。

原帖地址:http://www.cnblogs.com/qytan36/archive/2010/06/28/1766555.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章