unique ptr的使用和陷阱

2021-10-09 22:19:34 字數 2195 閱讀 7630

與shared_ptr不同,unique_ptr沒有定義類似make_shared的操作,因此只可以使用new來分配記憶體,並且由於unique_ptr不可拷貝和賦值,初始化unique_ptr必須使用直接初始化的方式。

unique_ptrup1(new int()); //okay,直接初始化

unique_ptrup2 = new int(); //error! 建構函式是explicit

unique_ptrup3(up1); //error! 不允許拷貝

與shared_ptr不同,unique_ptr擁有它所指向的物件,在某一時刻,只能有乙個unique_ptr指向特定的物件。當unique_ptr被銷毀時,它所指向的物件也會被銷毀。因此不允許多個unique_ptr指向同乙個物件,所以不允許拷貝與賦值。

unique_ptrup 

空的unique_ptr,可以指向型別為t的物件,預設使用delete來釋放記憶體

unique_ptrup(d) 

空的unique_ptr同上,接受乙個d型別的刪除器d,使用刪除器d來釋放記憶體

up = nullptr 

釋放up指向的物件,將up置為空

up.release() 

up放棄對它所指物件的控制權,並返回儲存的指標,將up置為空,不會釋放記憶體

up.reset(…) 

引數可以為 空、內建指標,先將up所指物件釋放,然後重置up的值.

前面說了unique_ptr不可拷貝和賦值,那要怎樣傳遞unique_ptr引數和返回unique_ptr呢? 

事實上不能拷貝unique_ptr的規則有乙個例外:我們可以拷貝或賦值乙個將要被銷毀的unique_ptr (c++ primer 5th p418)

//從函式返回乙個unique_ptr

unique_ptr func1(int a)

//返回乙個區域性物件的拷貝

unique_ptr func2(int a)

傳unique_ptr引數可以使用引用避免所有權的轉移,或者暫時的移交所有權

void func1(unique_ptr&up)

unique_ptrfunc2(unique_ptrup)

//使用up作為引數

unique_ptrup(new int(10));

//傳引用,不拷貝,不涉及所有權的轉移

func1(up);

//暫時轉移所有權,函式結束時返回拷貝,重新收回所有權

up = func2(unique_ptr(up.release()));

//如果不用up重新接受func2的返回值,這塊記憶體就洩漏了

類似shared_ptr,用unique_ptr管理非new物件、沒有析構函式的類時,需要向unique_ptr傳遞乙個刪除器。不同的是,unique_ptr管理刪除器的方式,我們必須在尖括號中unique_ptr指向型別後面提供刪除器的型別,在建立或reset乙個這種unique_ptr物件時,必須提供乙個相同型別的可呼叫物件(刪除器),這個刪除器接受乙個t*引數。

unique_ptr不允許兩個獨佔指標指向同乙個物件,在沒有裸指標的情況下,我們只能用release獲取記憶體的位址,同時放棄對物件的所有權,這樣就有效避免了多個獨佔指標同時指向乙個物件。 

而使用裸指標就很容器打破這一點

int *x(new int());

unique_ptrup1,up2;

//會使up1 up2指向同乙個記憶體

up1.reset(x);

up2.reset(x);

要避免寫這樣的程式

在呼叫u.release()時是不會釋放u所指的記憶體的,這時返回值就是對這塊記憶體的唯一索引,如果沒有使用這個返回值釋放記憶體或是儲存起來,這塊記憶體就洩漏了

unique ptr的使用和陷阱

與shared ptr不同,unique ptr沒有定義類似make shared的操作,因此只可以使用new來分配記憶體,並且由於unique ptr不可拷貝和賦值,初始化unique ptr必須使用直接初始化的方式。unique ptr up1 new int okay,直接初始化 unique...

unique ptr的相關使用

unique ptr由c 11中引入,用於替代不安全的auto ptr。unique ptr是一種定義在 memory 中的只能指標。它持有對物件的獨有權 這意味著,記憶體資源所有權可以轉移到另外乙個unique ptr,並且原始的unique ptr不再擁有次資源。實際使用中,建議將物件限制為由乙...

unique ptr使用總結

includestd unique ptrpname auto pname std make unique hello c 14 support make unique可以用乙個unique ptr初始化另外乙個unique ptr嗎?不可以,但是可以進行所有權轉移 vector可以裝unique ...