unique函数_走进C++11(三十四)unique_ptr
std::unique_ptr是C++11標準中用來取代std::auto_ptr的指針容器(在C++11中,auto_ptr被廢棄)。它不能與其它unique_ptr類型的指針對象共享所指對象的內存。這種”所有權”僅能夠通過標準庫的move函數來轉移。unique_ptr是一個刪除了拷貝構造函數、保留了移動構造函數的指針封裝類型。下面的腦圖總結了unique_ptr的特性:
1. ?一個unique_ptr"擁有"它所指向的對象。與shared_ptr不同,某個時刻只能有一個unique_ptr指向一個給定對象。當unique_ptr被銷毀時,它所指向的對象也被銷毀。
2. 與shared_ptr不同,在C++11中,沒有類似make_shared的標準庫函數返回一個unique_ptr。當定義一個unique_ptr時,需要將其綁定到一個new返回的指針上。至于為什么沒有make_unique的標準函數庫。標準的人說:“忘了”?????不過到了C++14,標準中加入了make_unique的定義。其實如果想用make_unique我們可以實現一個簡單版本的:
templatestd::unique_ptr make_unique(Args&&... args){ return std::unique_ptr(new T(std::forward(args)...));}3. 類似shared_ptr,初始化unique_ptr必須采用直接初始化形式。由于一個unique_ptr擁有它指向的對象,因此unique_ptr不支持普通的拷貝或賦值操作。雖然不能拷貝或賦值unique_ptr,但可以通過調用release或reset將指針的所有權從一個(非const)unique_ptr轉移給另一個unique。
不能拷貝unique_ptr的規則有一個例外:我們可以拷貝或賦值一個將要被銷毀的unique_ptr (C++ Primer 5th p418)
//從函數返回一個unique_ptrunique_ptr?func1(int?a){ return unique_ptr (new int(a));}//返回一個局部對象的拷貝unique_ptr?func2(int?a){ unique_ptr up(new int(a)); return up;}傳unique_ptr參數可以使用引用避免所有權的轉移,或者暫時的移交所有權
void func1(unique_ptr &up){ cout<}unique_ptr func2(unique_ptr up){ cout< return up;}//使用up作為參數unique_ptr up(new int(10));//傳引用,不拷貝,不涉及所有權的轉移func1(up);//暫時轉移所有權,函數結束時返回拷貝,重新收回所有權up = func2(unique_ptr (up.release()));//如果不用up重新接受func2的返回值,這塊內存就泄漏了4. 調用release會切斷unique_ptr和它原來管理的對象間的聯系。release返回的指針通過被用來初始化另一個智能指針或給另一個智能指針賦值。如果不用另一個智能指針來保存release返回的指針,程序就要負責資源的釋放。
5. 類似shared_ptr,unique_ptr默認情況下用delete釋放它指向的對象。與shared_ptr一樣,可以重載一個unique_ptr中默認的刪除器。但是,unique_ptr管理刪除器的方式與shared_ptr不同。
默認情況下,std::shared_ptr會調用delete來清空內存。當使用new[] 分配內存時,需要調用delete[] 來釋放內存,否則會有內存泄露。
可以通過以下代碼來自定義釋放內存的函數:
templatetypename?T?> struct array_deleter {?????void?operator?()(T?const?*?p) delete[] p; } };通過以下代碼來聲明std::shared_ptr指針:
std::shared_ptr<int> sp(new int[10], array_deleter<int>());此時,shared_ptr可正確的調用delete[]。
在C++11中,可以使用 std::default_delete代替上面自己寫的array_deleter:
std::shared_ptr<int> sp(new int[10], std::default_delete<int[]>());?
也可以使用一下的lambda表達式來自定義刪除函數
std::shared_ptr<int> sp(new int[10], [](int *p) { delete[] p; });?實際上,除非需要共享目標,否則unique_ptr更適合使用數組:
std::unique_ptr<int[]> up(new int[10]); // this will correctly call delete[]?上面代碼可以正確的分配空間,但是空間內的值都沒有初始化。如果需要默認初始化為0,可以使用下面的代碼:
std::unique_ptr<int[]> up(new int[10]()); // this will correctly call delete[] 初始化為06. unique_ptr的常用操作
unique_ptr up?
空的unique_ptr,可以指向類型為T的對象,默認使用delete來釋放內存
unique_ptr up(d)?
空的unique_ptr同上,接受一個D類型的刪除器d,使用刪除器d來釋放內存
up = nullptr?
釋放up指向的對象,將up置為空
up.release()?
up放棄對它所指對象的控制權,并返回保存的指針,將up置為空,不會釋放內存
up.reset(…)?
參數可以為?空、內置指針,先將up所指對象釋放,然后重置up的值.
總結
以上是生活随笔為你收集整理的unique函数_走进C++11(三十四)unique_ptr的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 雅马哈发电机换机油教程_奥迪老A4B7
- 下一篇: 键盘连击测试_测试梗欢迎补充