C++智能指针:unique_ptr详解
生活随笔
收集整理的這篇文章主要介紹了
C++智能指针:unique_ptr详解
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
文章目錄
- unique_ptr描述
- 聲明
- 作用
- 函數(shù)指針描述
- 總結(jié)
unique_ptr描述
聲明
頭文件:<memory>
模版類:
- 默認(rèn)類型
template <class T, class D = default_delete<T>> class unique_ptr - 數(shù)組類型
template <class T, class D> class unique_ptr<T[],D>;
作用
與shared_ptr最大的區(qū)別即是unique_ptr不能夠共享同一個(gè)地址,它對(duì)地址是獨(dú)占得。當(dāng)unique_ptr對(duì)象的生命周期結(jié)束,則它所引用的地址空間也會(huì)被釋放。
一個(gè)unique_ptr對(duì)象主要包含兩個(gè)部分
- 一個(gè)存儲(chǔ)指針:主要用來(lái)管理對(duì)象的地址空間。它是在構(gòu)造函數(shù)中分配的地址,并且能夠通過(guò)賦值運(yùn)算符以及reset成員函數(shù)進(jìn)行地址空間的重新指向。并且可以通過(guò)get和release成員變量進(jìn)行單獨(dú)訪問(wèn),獲取unique_ptr對(duì)象的地址空間。
- 一個(gè)存儲(chǔ)刪除器:刪除器為一個(gè)可以被調(diào)用的對(duì)象。主要被用來(lái)刪除unique_ptr對(duì)象的地址空間。同時(shí)能夠使用賦值運(yùn)算符進(jìn)行當(dāng)前對(duì)象的更改,并通過(guò)get_deleter成員函數(shù)進(jìn)行單獨(dú)訪問(wèn)。
函數(shù)指針描述
- 構(gòu)造函數(shù)
輸出如下://unique_ptr constructor example #include <iostream> #include <memory>int main () {std::default_delete<int> d;//默認(rèn)為空std::unique_ptr<int> u1;//使用null初始化指針,仍然為空std::unique_ptr<int> u2 (nullptr);//正常初始化std::unique_ptr<int> u3 (new int);//存儲(chǔ)指針正常初始化,之后并初始化刪除器的值,所以不為空std::unique_ptr<int> u4 (new int, d);//存儲(chǔ)指針正常初始化,之后刪除器使用默認(rèn)的構(gòu)造函數(shù)進(jìn)行初始化,所以u(píng)nique_ptr又為空了std::unique_ptr<int> u5 (new int, std::default_delete<int>());std::unique_ptr<int> u6 (std::move(u5));std::unique_ptr<int> u7 (std::move(u6));std::unique_ptr<int> u8 (std::auto_ptr<int>(new int));std::cout << "u1: " << (u1?"not null":"null") << '\n';std::cout << "u2: " << (u2?"not null":"null") << '\n';std::cout << "u3: " << (u3?"not null":"null") << '\n';std::cout << "u4: " << (u4?"not null":"null") << '\n';std::cout << "u5: " << (u5?"not null":"null") << '\n';std::cout << "u6: " << (u6?"not null":"null") << '\n';std::cout << "u7: " << (u7?"not null":"null") << '\n';std::cout << "u8: " << (u8?"not null":"null") << '\n';return 0; }u1: null u2: null u3: not null u4: not null u5: null u6: null u7: not null u8: not null - 析構(gòu)函數(shù);如果對(duì)象為空的unique_ptr,即使用get()==nullptr,則析構(gòu)函數(shù)無(wú)法產(chǎn)生作用
否則會(huì)正常刪除對(duì)象,就像get_deleter()函數(shù)一樣
輸出如下:// unique_ptr destructor example #include <iostream> #include <memory>int main () {auto deleter = [](int*p){delete p;std::cout << "[deleter called]\n";};std::unique_ptr<int,decltype(deleter)> foo (new int,deleter);std::cout << "foo " << (foo?"is not":"is") << " empty\n";return 0; // [deleter called] }foo is not empty [deleter called] operator=
輸出如下:// unique_ptr::operator= example #include <iostream> #include <memory>int main () {std::unique_ptr<int> foo;std::unique_ptr<int> bar;foo = std::unique_ptr<int>(new int (101)); // rvalue//std::move操作是將foo對(duì)象的地址以及空間內(nèi)容轉(zhuǎn)給bar,所以執(zhí)行之后foo變?yōu)榱薳mpty//之所以使用std::move操作是因?yàn)閡nique_ptr對(duì)象地址空間只能被一個(gè)對(duì)象獨(dú)享bar = std::move(foo); // using std::movestd::cout << "foo: ";if (foo) std::cout << *foo << '\n'; else std::cout << "empty\n";std::cout << "bar: ";if (bar) std::cout << *bar << '\n'; else std::cout << "empty\n";return 0; }foo: empty bar: 101std :: unique_ptr :: get成員,改成員函數(shù)返回被管理的unique_ptr對(duì)象,此函數(shù)的調(diào)用不會(huì)使unique_ptr釋放指針的所有權(quán)(即,它仍然負(fù)責(zé)在某個(gè)時(shí)刻刪除管理數(shù)據(jù))。因此,此函數(shù)返回的值不得用于構(gòu)造新的管理指針。為了活動(dòng)存儲(chǔ)指針,并且能夠正常釋放,則使用release()成員函數(shù)
輸出如下:// unique_ptr::get vs unique_ptr::release #include <iostream> #include <memory>int main () {// foo bar p// --- --- ---std::unique_ptr<int> foo; // nullstd::unique_ptr<int> bar; // null nullint* p = nullptr; // null null nullfoo = std::unique_ptr<int>(new int(10)); // (10) null null//這里經(jīng)過(guò)std::move之后foo的地址以及內(nèi)容轉(zhuǎn)移給了barstd::cout << "foo: " << foo.get() << std::endl;bar = std::move(foo); // null (10) nullstd::cout << "foo: " << foo.get() << std::endl;std::cout << "bar: " << bar.get() << std::endl;p = bar.get(); // null (10) (10)*p = 20; // null (20) (20)p = nullptr; // null (20) nullfoo = std::unique_ptr<int>(new int(30)); // (30) (20) nullp = foo.release(); // null (20) (30)*p = 40; // null (20) (40)std::cout << "foo: ";if (foo) std::cout << *foo << '\n'; else std::cout << "(null)\n";std::cout << "bar: ";if (bar) std::cout << *bar << '\n'; else std::cout << "(null)\n";std::cout << "p: ";if (p) std::cout << *p << '\n'; else std::cout << "(null)\n";std::cout << '\n';delete p; // the program is now responsible of deleting the object pointed to by p// bar deletes its managed object automaticallyreturn 0; }optionscompilationexecution foo: 0x817a10 foo: 0 bar: 0x817a10 foo: (null) bar: 20 p: 40std :: unique_ptr :: release
通過(guò)改成員函數(shù)的返回值以及空指針來(lái)釋放當(dāng)前unique_ptr指針的所有權(quán)
當(dāng)前調(diào)用并不會(huì)破壞管理對(duì)象,改成員函數(shù)不會(huì)刪除對(duì)象,而需要其他實(shí)體在某個(gè)時(shí)候刪除對(duì)象。如果想要強(qiáng)制刪除對(duì)象,需要使用reset或者賦值運(yùn)算符(std::move)
輸出如下:// unique_ptr::release example #include <iostream> #include <memory>int main () {std::unique_ptr<int> auto_pointer (new int);int * manual_pointer;*auto_pointer=10;std::cout << " auto_pointer " << auto_pointer.get() << std::endl;manual_pointer = auto_pointer.release();std::cout << " auto_pointer " << auto_pointer.get() << std::endl;std::cout << " manual_pointer " << manual_pointer<< std::endl;// (auto_pointer is now empty)std::cout << "manual_pointer points to " << *manual_pointer << '\n';delete manual_pointer;return 0; }auto_pointer 0x3afffa0auto_pointer 0manual_pointer 0x3afffa0 manual_pointer points to 10std::unique_ptr::reset
void reset (pointer p = pointer()) noexcept;
破壞掉當(dāng)前unique_ptr對(duì)象,并且獲取它所有權(quán)p,如果p是空的,則當(dāng)前unique_ptr對(duì)象也即為空
如果想要釋放當(dāng)前對(duì)象,并且并不破壞對(duì)象所指地址空間以及內(nèi)容,則使用release成員函數(shù)
輸出如下:// unique_ptr::reset example #include <iostream> #include <memory>int main () {std::unique_ptr<int> up; // empty//reset之后 up之前對(duì)象所指空間已經(jīng)被破壞,并重新接管up對(duì)象,分配新的地址空間up.reset (new int); // takes ownership of pointer//可以看到地址空間已經(jīng)由之前的null變?yōu)橹匦路峙涞目臻gstd::cout << *up << " " << up.get() << '\n';*up=5;std::cout << *up << " " << up.get() << '\n';up.reset (new int); // deletes managed object, acquires new pointer*up=10;std::cout << *up << " " << up.get() << '\n';up.reset(); // deletes managed objectreturn 0; }0 0xd7dc70 5 0xd7dc70 10 0xd7dc90std::unique_ptr::swap交換對(duì)象空間以及內(nèi)容,且并不破壞地址空間
輸出如下:// unique_ptr::swap example#include <iostream>#include <memory>int main () {std::unique_ptr<int> foo (new int(10));std::unique_ptr<int> bar (new int(20));std::cout << "foo: " << *foo << " " << foo.get() << '\n';std::cout << "bar: " << *bar << " " << bar.get() << '\n';foo.swap(bar);std::cout << "foo: " << *foo << " " << foo.get() << '\n';std::cout << "bar: " << *bar << " " << bar.get() << '\n';return 0;}foo: 10 0x2cd9ae0 bar: 20 0x2cd9b00 foo: 20 0x2cd9b00 bar: 10 0x2cd9ae0
總結(jié)
- shared_ptr地址空間無(wú)法被多個(gè)智能指針共享,當(dāng)實(shí)際當(dāng)前對(duì)象地址作用域結(jié)束,則改對(duì)象所占有地址空間將被釋放
- 使用release成員函數(shù)可以轉(zhuǎn)移unique_ptr隊(duì)形的所有圈,即將unique_ptr對(duì)象轉(zhuǎn)為非unique_ptr對(duì)象,并不破壞地址
- 使用
reset會(huì)重置對(duì)象地址空間,并重新分配。會(huì)破壞地址空間 - 使用賦值元算符,和reset函數(shù)類似重新指定地址空間,同樣會(huì)破壞地址空間
- unique_ptr對(duì)象的返回智能使用成員函數(shù)
get
總結(jié)
以上是生活随笔為你收集整理的C++智能指针:unique_ptr详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 大家感觉万圣节小炮的皮肤怎么样
- 下一篇: ceph-kvstore-tool 工具