C++智能指针中unique_ptr部分内容的讲解
生活随笔
收集整理的這篇文章主要介紹了
C++智能指针中unique_ptr部分内容的讲解
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
參考鏈接
- std::unique_ptr
介紹
- 定義位于頭文件<memory>
- std::unique_ptr 是通過指針占有并管理另一對象,并在 unique_ptr 離開作用域時(shí)釋放該對象的智能指針。 在下列兩者之一發(fā)生時(shí)用關(guān)聯(lián)的刪除器釋放對象:1,銷毀了管理的 unique_ptr 對象;2, 通過 operator= 或 reset() 賦值另一指針給管理的 unique_ptr 對象。
- 通過調(diào)用 get_deleter()(ptr) ,用潛在為用戶提供的刪除器釋放對象。默認(rèn)刪除器用 delete 運(yùn)算符,它銷毀對象并解分配內(nèi)存。
- unique_ptr 亦可以不占有對象,該情況下稱它為空 (empty)。 std::unique_ptr 有兩個(gè)版本: 1) 管理單個(gè)對象(例如以 new 分配) 2) 管理動態(tài)分配的對象數(shù)組(例如以 new[] 分配)
- 類滿足可移動構(gòu)造?(MoveConstructible)?和可移動賦值?(MoveAssignable)?的要求,但不滿足可復(fù)制構(gòu)造?(CopyConstructible)?或可復(fù)制賦值?(CopyAssignable)?的要求。
- 只有非 const 的?unique_ptr?能轉(zhuǎn)移被管理對象的所有權(quán)給另一?unique_ptr?。若對象的生存期為?const?std::unique_ptr?所管理,則它被限定在創(chuàng)建指針的作用域中。
- std::unique_ptr?常用于管理對象的生存期,包含:
- 通過正常退出和經(jīng)由異常退出兩者上的受保證刪除,提供異常安全,給處理擁有動態(tài)生存期的對象的類和函數(shù)
- 傳遞獨(dú)占的擁有動態(tài)生存期的對象的所有權(quán)到函數(shù)
- 從函數(shù)獲得獨(dú)占的擁有動態(tài)生存期對象的所有權(quán)
- 作為具移動容器的元素類型,例如保有指向動態(tài)分配對象的指針的?std::vector?(例如,若想要多態(tài)行為)
- std::unique_ptr?可為不完整類型?T?構(gòu)造,例如用于改善用作?pImpl 手法中柄的用途。若使用默認(rèn)刪除器,則?T?必須在代碼中調(diào)用刪除器點(diǎn)處完整,這發(fā)生于析構(gòu)函數(shù)、移動賦值運(yùn)算符和?std::unique_ptr?的?reset?成員函數(shù)中。(相反地,?std::shared_ptr?不能從指向不完整類型的裸指針構(gòu)造,但可于?T?不完整處銷毀)。注意若?T?是類模板特化,則以?unique_ptr?為運(yùn)算數(shù)的使用,如?!p?,因?ADL?而要求?T?的形參完整。
- 若?T?是某基類?B?的派生類,則?std::unique_ptr<T>?可隱式轉(zhuǎn)換為?std::unique_ptr<B>。產(chǎn)生的?std::unique_ptr<B>?的默認(rèn)刪除器將使用?B?的?operator delete?,這導(dǎo)致未定義行為,除非?B?的析構(gòu)函數(shù)為虛。注意?std::shared_ptr?表現(xiàn)有別:?std::shared_ptr<B>?將使用類型?T?的?operator delete?,而且即使?B?的析構(gòu)函數(shù)非虛,也會正確刪除被占有對象。
- 不同于?std::shared_ptr?,?std::unique_ptr?可通過任何滿足可空指針?(NullablePointer)?的定制柄類型管理對象。例如,這允許管理位于共享內(nèi)存,但提供定義?typedef?boost::offset_ptr?pointer;?或其他綴飾指針的?Deleter?的對象。
參考代碼
#include <iostream> #include <vector> #include <memory> #include <cstdio> #include <fstream> #include <cassert> #include <functional>struct B {virtual void bar() { std::cout << "B::bar\n"; }virtual ~B() = default; }; struct D : B {D() { std::cout << "D::D\n"; }~D() { std::cout << "D::~D\n"; }void bar() override { std::cout << "D::bar\n"; } };// 消費(fèi) unique_ptr 的函數(shù)能以值或以右值引用接收它 std::unique_ptr<D> pass_through(std::unique_ptr<D> p) {p->bar();return p; }void close_file(std::FILE* fp) { std::fclose(fp); }int main() {std::cout << "unique ownership semantics demo\n";{auto p = std::make_unique<D>(); // p 是占有 D 的 unique_ptrauto q = pass_through(std::move(p)); assert(!p); // 現(xiàn)在 p 不占有任何內(nèi)容并保有空指針q->bar(); // 而 q 占有 D 對象} // ~D 調(diào)用于此std::cout << "Runtime polymorphism demo\n";{std::unique_ptr<B> p = std::make_unique<D>(); // p 是占有 D 的 unique_ptr// 作為指向基類的指針p->bar(); // 虛派發(fā)std::vector<std::unique_ptr<B>> v; // unique_ptr 能存儲于容器v.push_back(std::make_unique<D>());v.push_back(std::move(p));v.emplace_back(new D);for(auto& p: v) p->bar(); // 虛派發(fā)} // ~D called 3 timesstd::cout << "Custom deleter demo\n";std::ofstream("demo.txt") << 'x'; // 準(zhǔn)備要讀的文件{std::unique_ptr<std::FILE, void (*)(std::FILE*) > fp(std::fopen("demo.txt", "r"),close_file);if(fp) // fopen 可以打開失敗;該情況下 fp 保有空指針std::cout << (char)std::fgetc(fp.get()) << '\n';} // fclose() 調(diào)用于此,但僅若 FILE* 不是空指針// (即 fopen 成功)std::cout << "Custom lambda-expression deleter demo\n";{std::unique_ptr<D, std::function<void(D*)>> p(new D, [](D* ptr){std::cout << "destroying from a custom deleter...\n";delete ptr;}); // p 占有 Dp->bar();} // 調(diào)用上述 lambda 并銷毀 Dstd::cout << "Array form of unique_ptr demo\n";{std::unique_ptr<D[]> p{new D[3]};} // 調(diào)用 ~D 3 次 }?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的C++智能指针中unique_ptr部分内容的讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 女子怕头秃3个月不洗头 惊喜长出碎发 却
- 下一篇: python 版本2和3 在/取模方面的