最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c++ 智能指針基礎(chǔ)詳解

 更新時(shí)間:2021年02月18日 17:03:43   作者:Er_HU  
這篇文章主要介紹了c++ 智能指針基礎(chǔ)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下

簡(jiǎn)介

在現(xiàn)代 C++ 編程中,標(biāo)準(zhǔn)庫(kù)包含了智能指針(Smart pointers)。

智能指針用來確保程序不會(huì)出現(xiàn)內(nèi)存和資源的泄漏,并且是"異常安全"(exception-safe)的。

智能指針的使用

智能指針定義在頭文件 memory 里的命名空間 std 中。它對(duì)于資源獲取即初始化(RAII, Resource Acquisition Is Initialization) 編程理念至關(guān)重要。該理念的目的是保證對(duì)象初始化的時(shí)候也是資源獲取的時(shí)候,從而使對(duì)象的所有資源在單行代碼中創(chuàng)建。

實(shí)踐中,RAII 的主要原則就是把任何在堆上分配的資源(比如動(dòng)態(tài)分配的內(nèi)存或者系統(tǒng)對(duì)象的處理)的所有權(quán)提供給在棧上分配的對(duì)象(其析構(gòu)函數(shù)包含釋放資源及相關(guān)清理的代碼)。

大多數(shù)時(shí)候,當(dāng)你初始化一個(gè)原始指針或者資源句柄使其指向?qū)嶋H的資源時(shí),立即將其傳給智能指針。

在現(xiàn)代 C++ 中,原始指針只用于包含在局部作用域,循環(huán)或者工具函數(shù)的小塊代碼中(對(duì)性能有要求,并且對(duì)資源的所有權(quán)也不容易混淆)。

原始指針和智能指針的聲明比較如下:

void UseRawPointer()
{
 // Using a raw pointer -- not recommended.
 Song* pSong = new Song(L"Nothing on You", L"Bruno Mars"); 

 // Use pSong...

 // Don't forget to delete!
 delete pSong; 
}

void UseSmartPointer()
{
 // Declare a smart pointer on stack and pass it the raw pointer.
 unique_ptr<Song> song2(new Song(L"Nothing on You", L"Bruno Mars"));

 // Use song2...
 wstring s = song2->duration_;
 //...

} // song2 is deleted automatically here.

如上所示,智能指針是一個(gè)在棧上聲明的類模板,并由指向分配在堆上的對(duì)象的原始指針初始化。當(dāng)智能指針初始化后,它就擁有了原始指針的所有權(quán)。這意味著智能指針需要負(fù)責(zé)原始指針指向的內(nèi)存釋放。智能指針的析構(gòu)函數(shù)包含了 delete 的調(diào)用,并且由于智能指針是在棧上聲明的,其析構(gòu)函數(shù)會(huì)在智能指針對(duì)象離開作用域時(shí)被調(diào)用,即使在棧中發(fā)生了異常。

通過使用指針運(yùn)算符(-> 和 *)訪問被封裝的指針,智能指針類重載了這些運(yùn)算符以返回被封裝的原始指針。

C++ 智能指針的理念類似于在 C# 語(yǔ)言中創(chuàng)建對(duì)象的過程:創(chuàng)建對(duì)象后讓系統(tǒng)負(fù)責(zé)在正確的時(shí)間將其刪除。不同之處在于,沒有獨(dú)立的垃圾回收器運(yùn)行于后臺(tái);內(nèi)存是按照標(biāo)準(zhǔn) C++ 規(guī)范對(duì)內(nèi)存進(jìn)行管理的,使運(yùn)行時(shí)環(huán)境更加快速和高效。

[!重要]

總是在單獨(dú)的行上創(chuàng)建智能指針,而不是在參數(shù)列表中,從而避免由于特定的參數(shù)列表分配規(guī)則出現(xiàn)一些輕微的內(nèi)存泄漏

以下示例顯示了 C++ 標(biāo)準(zhǔn)庫(kù)中的 unique_ptr 是如何封裝指向大型對(duì)象的指針的。

class LargeObject
{
public:
 void DoSomething(){}
};

void ProcessLargeObject(const LargeObject& lo){}

void SmartPointerDemo()
{ 
 // Create the object and pass it to a smart pointer
 std::unique_ptr<LargeObject> pLarge(new LargeObject());

 //Call a method on the object
 pLarge->DoSomething();

 // Pass a reference to a method.
 ProcessLargeObject(*pLarge);

} //pLarge is deleted automatically when function block goes out of scope.

上述示例演示了使用智能指針的關(guān)鍵步驟:

  1. 將智能指針聲明為局部變量(不要在智能指針上使用 new 或者 malloc 表達(dá)式)。
  2. 在類型參數(shù)上,指定被封裝指針指向的對(duì)象類型。
  3. 將指向由 new 創(chuàng)建的對(duì)象的指針傳給智能指針的構(gòu)造函數(shù)。
  4. 使用重載的操作符 -> 和 * 來訪問對(duì)象。
  5. 讓智能指針來 delete 對(duì)象。

智能指針在設(shè)計(jì)上兼顧了內(nèi)存和性能的高效性。例如,unique_ptr 唯一的數(shù)據(jù)成員是被封裝的原始指針,這意味著 unique_ptr 具有原始指針同樣地大小,4 字節(jié)或者 8 字節(jié)。通過智能指針重載的操作符 -> 和 * 來訪問并不比直接使用原始指針來訪問慢多少。

智能指針有其自己的成員函數(shù),通過 . 來訪問。例如,一些 C++ 標(biāo)準(zhǔn)庫(kù)的智能指針有用于重置的成員函數(shù)來釋放對(duì)原始指針的所有權(quán)。這可以用于在智能指針超出作用域前釋放智能指針管理的內(nèi)存,看下面的示例:

void SmartPointerDemo2()
{
 // Create the object and pass it to a smart pointer
 std::unique_ptr<LargeObject> pLarge(new LargeObject());

 //Call a method on the object
 pLarge->DoSomething();

 // Free the memory before we exit function block.
 pLarge.reset();

 // Do some other work...

}

智能指針通常提供了獲取原始指針的方式。 C++ 標(biāo)準(zhǔn)庫(kù)中的智能指針包含了成員函數(shù) get 來獲取原始指針。 CComPtr 有公共的類成員 p。通過獲取原始指針,你能夠使用智能指針來管理你自己代碼涉及的內(nèi)存并依然能夠?qū)⒃贾羔槀鬟f給不支持智能指針的代碼。

void SmartPointerDemo4()
{
 // Create the object and pass it to a smart pointer
 std::unique_ptr<LargeObject> pLarge(new LargeObject());

 //Call a method on the object
 pLarge->DoSomething();

 // Pass raw pointer to a legacy API
 LegacyLargeObjectFunction(pLarge.get()); 
}

智能指針的種類

以下部分總結(jié)了在 Windows 環(huán)境下不同種類的智能指針,以及如何使用它們。

C++ 標(biāo)準(zhǔn)庫(kù)中的智能指針

優(yōu)先使用下列智能指針來封裝原始指針指向的純舊對(duì)象(plain old C++ objects,POCO):

unique_ptr

  • 對(duì)封裝的原始指針是獨(dú)占的
  • 默認(rèn)用于 POCO,除非你明確的知道你需要一個(gè) shared_ptr
  • 可以移入新的所有者,但不能拷貝或者共享
  • 替代 auto_ptr,auto_ptr 已作廢
  • 對(duì)比 boost::scoped_ptr,unique_ptr 更加小巧和高效
  • 長(zhǎng)度為一個(gè)指針的大小,并且支持右值引用來快速執(zhí)行 C++ 標(biāo)準(zhǔn)庫(kù)容器的插入和遍歷操作

shared_ptr

  • 引用計(jì)數(shù)智能指針
  • 當(dāng)你需要將原始指針分派給多個(gè)所有者時(shí)使用,例如,當(dāng)你從容器返回一個(gè)指針的拷貝并且想要保留它
  • 原始指針不會(huì)被 delete 直到所有的 shared_ptr 超出作用域或者放棄所有權(quán)。
  • 長(zhǎng)度為兩個(gè)指針的大小,一個(gè)用于對(duì)象,另一個(gè)用于包含引用計(jì)數(shù)的共享控制塊

weak_ptr

  • 結(jié)合 shared_ptr 使用的特殊智能指針。
  • weak_ptr 提供了對(duì)被一個(gè)或者多個(gè) shared_ptr 所擁有的對(duì)象的訪問,但不參與引用計(jì)數(shù)。
  • 如果你想要監(jiān)測(cè)某個(gè)對(duì)象,不要求其不被釋放,可以使用 weak_ptr
  • 在某些情況下,用于解決 shared_ptr 實(shí)例間的循環(huán)引用。

擴(kuò)展

  • 用于 COM 組件的智能指針
  • 用于 POCO對(duì)象的ATL智能指針

引用

Microsoft Docs (https://docs.microsoft.com/en-us/cpp/cpp/smart-pointers-modern-cpp?view=msvc-160)

以上就是c++ 智能指針基礎(chǔ)詳解的詳細(xì)內(nèi)容,更多關(guān)于c++ 智能指針的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • VS2019實(shí)現(xiàn)C++的第一個(gè)MFC程序

    VS2019實(shí)現(xiàn)C++的第一個(gè)MFC程序

    本文主要介紹了VS2019實(shí)現(xiàn)C++的第一個(gè)MFC程序,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • VC++在TXT文件指定位置追加內(nèi)容的方法

    VC++在TXT文件指定位置追加內(nèi)容的方法

    這篇文章主要介紹了VC++在TXT文件指定位置追加內(nèi)容的方法,功能較為實(shí)用,需要的朋友可以參考下
    2014-08-08
  • C語(yǔ)言實(shí)現(xiàn)時(shí)間戳轉(zhuǎn)日期的算法(推薦)

    C語(yǔ)言實(shí)現(xiàn)時(shí)間戳轉(zhuǎn)日期的算法(推薦)

    下面小編就為大家?guī)硪黄狢語(yǔ)言實(shí)現(xiàn)時(shí)間戳轉(zhuǎn)日期的算法(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • 淺談C++性能榨汁機(jī)之偽共享

    淺談C++性能榨汁機(jī)之偽共享

    使給定內(nèi)存位置被一個(gè)線程所訪問,可能還是會(huì)有乒乓緩存的存在,是因?yàn)榱硪环N叫做偽共享(false sharing)的效應(yīng)。即使數(shù)據(jù)存儲(chǔ)在緩存行中,多個(gè)線程對(duì)數(shù)據(jù)中的成員進(jìn)行訪問時(shí),硬件緩存還是會(huì)產(chǎn)生乒乓緩存。本文將介紹C++中的偽共享
    2021-06-06
  • Matlab利用垂距法實(shí)現(xiàn)提取離散坐標(biāo)數(shù)據(jù)特征點(diǎn)

    Matlab利用垂距法實(shí)現(xiàn)提取離散坐標(biāo)數(shù)據(jù)特征點(diǎn)

    垂距法是指根據(jù)中間頂點(diǎn)到其前、后兩相鄰頂點(diǎn)連線的距離的大小,來確定是否保留該頂點(diǎn)的一種線要素頂點(diǎn)壓縮算法。本文將利用這一算法實(shí)現(xiàn)提取離散坐標(biāo)數(shù)據(jù)特征點(diǎn),需要的可以參考下
    2022-04-04
  • VisualStudio?2015?新建C/C++項(xiàng)目的圖文教程

    VisualStudio?2015?新建C/C++項(xiàng)目的圖文教程

    visual?studio是一個(gè)比較集成的開發(fā)平臺(tái),本文主要介紹了VisualStudio?2015?新建C/C++項(xiàng)目的圖文教程,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • C++中的opeartor?new和placement?new使用步驟

    C++中的opeartor?new和placement?new使用步驟

    這篇文章主要介紹了C++中的opeartor?new和placement?new詳解,在很多情況下,placement?new的使用方法和其他普通的new有所不同。這里提供了它的使用步驟,需要的朋友可以參考下
    2022-10-10
  • c++ priority_queue用法入門超詳細(xì)教程

    c++ priority_queue用法入門超詳細(xì)教程

    priority_queue即優(yōu)先級(jí)隊(duì)列,它的使用場(chǎng)景很多,它底層是用大小根堆實(shí)現(xiàn)的,可以用log(n)的時(shí)間動(dòng)態(tài)地維護(hù)數(shù)據(jù)的有序性,這篇文章主要介紹了c++ priority_queue用法入門超詳細(xì)教程,需要的朋友可以參考下
    2023-12-12
  • 一文詳解Qt如何優(yōu)雅的進(jìn)行界面布局

    一文詳解Qt如何優(yōu)雅的進(jìn)行界面布局

    使? Qt 在界?上創(chuàng)建的控件, 都是通過 “絕對(duì)定位” 的?式來設(shè)定的,這種設(shè)定?式其實(shí)并不?便,尤其是界?如果內(nèi)容?較多, 不好計(jì)算,所以Qt 引??布局管理器 (Layout)?機(jī)制, 來解決上述問題,需要的朋友可以參考下
    2024-05-05
  • 解決C++ fopen按行讀取文件及所讀取的數(shù)據(jù)問題

    解決C++ fopen按行讀取文件及所讀取的數(shù)據(jù)問題

    今天小編就為大家分享一篇解決C++ fopen按行讀取文件及所讀取的數(shù)據(jù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07

最新評(píng)論

大渡口区| 牡丹江市| 南乐县| 军事| 日喀则市| 景洪市| 浦北县| 都昌县| 集贤县| 赞皇县| 清远市| 浑源县| 南丹县| 安达市| 绵阳市| 杭锦旗| 花垣县| 奉节县| 棋牌| 方城县| 石景山区| 德格县| 黄骅市| 日照市| 惠安县| 彭州市| 五家渠市| 施甸县| 青龙| 会同县| 哈巴河县| 朝阳市| 洛宁县| 盐亭县| 大关县| 青铜峡市| 株洲县| 崇左市| 贵港市| 东莞市| 兴山县|