1. 程式人生 > >c++智慧指標(三)之shared_ptr和new結合使用

c++智慧指標(三)之shared_ptr和new結合使用

shared_ptr和new結合使用

我們除了使用make_shared來初始化一個智慧指標,還可以使用new返回的指標來初始化智慧指標。

shared_ptr<int> p1(new int(42));//p1指向一個值為42的int
shared_ptr<int> p2 = new int(1024);//錯誤,不能將一個內建指標隱式轉化為智慧指標。

我們不能將一個內建指標隱式轉化為智慧指標。

    shared_ptr<int> clone(int p){
        return new int(p);//錯誤,不能隱式轉化
    }

    shared_ptr
<int> clone(int p){ return shared_ptr<int>(new int(p));//正確 }

不要混合使用普通指標和智慧指標!

void process(shared_ptr<int> ptr){
    //使用ptr
}//離開作用域,ptr被銷燬

例如,下面這段程式碼就是正確的:

shared_ptr<int> p(new int(42));//p的引用計數為1
process(p);//拷貝p,增加的p的引用計數,這時p的引用計數為2
int i = *p;//此時,離開process作用域,p的引用計數減1,變為1,

下面這段程式碼就有錯誤:

int *x(new int(24));//x是一個普通指標,不是智慧指標
process(x);//錯誤,不能將int*轉化為一個shared_ptr
process(shared_ptr<int>(x));//合法的,但是離開process作用域的時候,這個智慧指標指向的記憶體會被釋放
int j = *x;//未定義的,因為x是個空懸指標,記憶體已經被釋放了

不要使用get初始化另一個智慧指標或者為智慧指標賦值

有時候,我們需要向不能使用智慧指標的程式碼傳遞一個內建指標。智慧指標型別定義了一個名為get的函式,它返回一個內建指標 指向智慧指標所管理的物件。

shared_ptr<int> p(new int(42));
int *q = p.get();//返回了一個內建指標,但是使用q的時候要注意,不要讓它管理的記憶體釋放
{
    shared_ptr<int>(q);
}//程式塊結束,q被銷燬,它指向的記憶體被釋放
int foo = *p;//未定義,p指向的記憶體已經被釋放了

reset操作

shared_ptr<int> p (new int(1024));//
p.reset(new string("hello));//p指向一個新的物件

reset一般會和unique一起使用,來控制多個shared_ptr共享的物件。

shared_ptr<int> p(new int(42));
    if (!p.unique()){
        p.reset(new string("hello"));//我們不是唯一使用者,分配新的拷貝
    }
    *p += newVal;//現在我們知道我們是唯一的使用者,可以改變物件的值