日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

c++11之智能指针

發(fā)布時(shí)間:2024/3/26 c/c++ 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++11之智能指针 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

一,什么是智能指針

二,共享的智能指針shared_ptr

1. shared_ptr的初始化

3.?指定刪除器

?三,獨(dú)占的智能指針unique_ptr

?1. 初始化

?2. 刪除器

四,?弱引用的智能指針weak_ptr

?1 初始化

?2.常用函數(shù)


前言:面試的時(shí)候被問(wèn)到智能指針了,答的很糟糕,這幾天重新學(xué)習(xí)了智能指針。下面是我對(duì)c++智能指針的理解與總結(jié),希望能幫到大家,同時(shí)提升自己。

一,什么是智能指針

在C++中沒(méi)有垃圾回收機(jī)制,必須自己釋放分配的內(nèi)存,否則就會(huì)造成內(nèi)存泄露。解決這個(gè)問(wèn)題最有效的方法是使用智能指針(smart pointer)。智能指針是存儲(chǔ)指向動(dòng)態(tài)分配(堆)對(duì)象指針的類,用于生存期的控制,能夠確保在離開(kāi)指針?biāo)谧饔糜驎r(shí),自動(dòng)地銷毀動(dòng)態(tài)分配的對(duì)象,防止內(nèi)存泄露。智能指針的核心實(shí)現(xiàn)技術(shù)是引用計(jì)數(shù),每使用它一次,內(nèi)部引用計(jì)數(shù)加1,每析構(gòu)一次內(nèi)部的引用計(jì)數(shù)減1,減為0時(shí),刪除所指向的堆內(nèi)存。

  • ?c++中用的最多的是下面三種智能指針

C++11中提供了三種智能指針,使用這些智能指針時(shí)需要引用頭文件<memory>

  • std::shared_ptr:共享的智能指針
  • std::unique_ptr:獨(dú)占的智能指針
  • std::weak_ptr:弱引用的智能指針,它不共享指針,不能操作資源,是用來(lái)監(jiān)視shared_ptr的。
  • ?下面對(duì)他們分別進(jìn)行分析

二,共享的智能指針shared_ptr

  • 首先了解一下基本概念,再看代碼,會(huì)學(xué)的很快

1. shared_ptr的初始化

?共享智能指針是指多個(gè)智能指針可以同時(shí)管理同一塊有效的內(nèi)存,共享智能指針shared_ptr?是一個(gè)模板類,如果要進(jìn)行初始化有三種方式:通過(guò)構(gòu)造函數(shù)、std::make_shared輔助函數(shù)以及reset方法。共享智能指針對(duì)象初始化完畢之后就指向了要管理的那塊堆內(nèi)存,如果想要查看當(dāng)前有多少個(gè)智能指針同時(shí)管理著這塊內(nèi)存可以使用共享智能指針提供的一個(gè)成員函數(shù)use_count

2.獲取原始指針

?對(duì)應(yīng)基礎(chǔ)數(shù)據(jù)類型來(lái)說(shuō),通過(guò)操作智能指針和操作智能指針管理的內(nèi)存效果是一樣的,可以直接完成數(shù)據(jù)的讀寫。但是如果共享智能指針管理的是一個(gè)對(duì)象,那么就需要取出原始內(nèi)存的地址再操作,可以調(diào)用共享智能指針類提供的get()方法得到原始地址

3.?指定刪除器

?當(dāng)智能指針管理的內(nèi)存對(duì)應(yīng)的引用計(jì)數(shù)變?yōu)?的時(shí)候,這塊內(nèi)存就會(huì)被智能指針析構(gòu)掉了。另外,我們?cè)诔跏蓟悄苤羔樀臅r(shí)候也可以自己指定刪除動(dòng)作,這個(gè)刪除操作對(duì)應(yīng)的函數(shù)被稱之為刪除器這個(gè)刪除器函數(shù)本質(zhì)是一個(gè)回調(diào)函數(shù),我們只需要進(jìn)行實(shí)現(xiàn),其調(diào)用是由智能指針完成的。

  • ?上面三個(gè)基本知識(shí)點(diǎn)了解以后就可以輕松的閱讀代碼了(代碼注釋都非常的詳細(xì)哦!)
#include <iostream> using namespace std; #include <string> #include <memory>class Test { public:Test() : m_num(0){cout << "construct Test..." << endl;}Test(int x) : m_num(0){cout << "construct Test, x = " << x << endl;}Test(string str) : m_num(0){cout << "construct Test, str = " << str << endl;}~Test(){cout << "destruct Test..." << endl;}void setValue(int v){this->m_num = v;}void print(){cout << "m_num: " << this->m_num << endl;}private:int m_num; };int main() {/*-------------------------- 一,初始化智能指針shared_ptr ------------------------------*///1.通過(guò)構(gòu)造函數(shù)初始化shared_ptr<int> ptr1(new int(3));cout << "ptr1管理的內(nèi)存引用計(jì)數(shù): " << ptr1.use_count() << endl;//2.通過(guò)移動(dòng)和拷貝構(gòu)造函數(shù)初始化shared_ptr<int> ptr2 = move(ptr1);cout << "ptr1管理的內(nèi)存引用計(jì)數(shù): " << ptr1.use_count() << endl;cout << "ptr2管理的內(nèi)存引用計(jì)數(shù): " << ptr2.use_count() << endl;shared_ptr<int> ptr3 = ptr2;cout << "ptr2管理的內(nèi)存引用計(jì)數(shù): " << ptr2.use_count() << endl;cout << "ptr3管理的內(nèi)存引用計(jì)數(shù): " << ptr3.use_count() << endl;//3.通過(guò) std::make_shared初始化shared_ptr<int> ptr4 = make_shared<int>(8);shared_ptr<Test> ptr5 = make_shared<Test>(7);shared_ptr<Test> ptr6 = make_shared<Test>("GOOD LUCKLY!");//4.通過(guò)reset初始化ptr6.reset(); //重置ptr6, ptr6的引用基數(shù)為0cout << "ptr6管理的內(nèi)存引用計(jì)數(shù): " << ptr6.use_count() << endl;ptr5.reset(new Test("hello"));cout << "ptr5管理的內(nèi)存引用計(jì)數(shù): " << ptr5.use_count() << endl;cout << endl;cout << endl;/*-------------------------- 二,共享智能指針shared_ptr的使用 ------------------------------*///1.方法一Test* t = ptr5.get();t->setValue(1000);t->print();//2.方法二ptr5->setValue(7777);ptr5->print();printf("\n\n");/*------------------------------------ 三,指定刪除器 -----------------------------------*///1.簡(jiǎn)單舉例shared_ptr<Test> ppp(new Test(100), [](Test* t) {//釋放內(nèi)存cout << "Test對(duì)象的內(nèi)存被釋放了......." << endl;delete t;});printf("----------------------------------------------------------------------\n");2.如果是數(shù)組類型的地址,就需要自己寫指定刪除器,否則內(nèi)存無(wú)法全部釋放//shared_ptr<Test> p1(new Test[5], [](Test* t) {// delete[]t;// });//3.也可以使用c++給我們提供的 默認(rèn)刪除器函數(shù)(函數(shù)模板)shared_ptr<Test> p2(new Test[3], default_delete<Test[]>());//4.c++11以后可以這樣寫 也可以自動(dòng)釋放內(nèi)存shared_ptr<Test[]> p3(new Test[3]);return 0; }

?另外,我們還可以自己封裝一個(gè)函數(shù)模板make_shared_array方法來(lái)讓shared_ptr支持?jǐn)?shù)組,代碼如下:

#include <iostream> #include <memory> #include <string> using namespace std;//有了這個(gè)函數(shù)模板,我們就不用自己去釋放數(shù)組類型的地址了 template <typename T> shared_ptr<T> make_share_array(size_t size) {//返回匿名對(duì)象return shared_ptr<T>(new T[size], default_delete<T[]>()); }int main() {shared_ptr<int> ptr1 = make_share_array<int>(10);cout << ptr1.use_count() << endl;shared_ptr<string> ptr2 = make_share_array<string>(7);cout << ptr2.use_count() << endl;return 0; }

?三,獨(dú)占的智能指針unique_ptr

  • 首先了解一下基本概念,再看代碼,會(huì)學(xué)的很快

?1. 初始化

std::unique_ptr是一個(gè)獨(dú)占型的智能指針,它不允許其他的智能指針共享其內(nèi)部的指針,可以通過(guò)它的構(gòu)造函數(shù)初始化一個(gè)獨(dú)占智能指針對(duì)象,但是不允許通過(guò)賦值將一個(gè)unique_ptr賦值給另一個(gè)unique_ptr。

?2. 刪除器

?unique_ptr指定刪除器和shared_ptr指定刪除器是有區(qū)別的,unique_ptr指定刪除器的時(shí)候需要確定刪除器的類型,所以不能像shared_ptr那樣直接指定刪除器

#include <iostream> using namespace std; #include <string> #include <memory> #include <functional>class Test { public:Test() : m_num(0){cout << "construct Test..." << endl;}Test(int x) : m_num(1){cout << "construct Test, x = " << x << endl;}Test(string str) : m_num(2){cout << "construct Test, str = " << str << endl;}~Test(){cout << "destruct Test..." << endl;}void setValue(int v){this->m_num = v;}void print(){cout << "m_num: " << this->m_num << endl;}private:int m_num; };int main() {/*-------------------------- 一,初始化智能指針unique_ptr ------------------------------*///1.通過(guò)構(gòu)造函數(shù)初始化unique_ptr<int> ptr1(new int(3));//2.通過(guò)移動(dòng)函數(shù)初始化unique_ptr<int> ptr2 = move(ptr1);//.通過(guò)reset初始化ptr2.reset(new int(7));/*-------------------------- 二,unique_ptr的使用 ------------------------------*///1.方法一unique_ptr<Test> ptr3(new Test(666));Test* pt = ptr3.get();pt->setValue(6);pt->print();//2.方法二ptr3->setValue(777);ptr3->print();/*------------------------------------ 三,指定刪除器 -----------------------------------*///1.函數(shù)指針類型//using ptrFunc = void(*)(Test*);//unique_ptr<Test, ptrFunc> ptr4(new Test("hello"), [](Test* t) {// cout << "-----------------------" << endl;// delete t;// });//2.仿函數(shù)類型(利用可調(diào)用對(duì)象包裝器)unique_ptr<Test, function<void(Test*)>> ptr4(new Test("hello"), [](Test* t) {cout << "-----------------------" << endl;delete t;});/*---------- 四,獨(dú)占(共享)的智能指針可以管理數(shù)組類型的地址,能夠自動(dòng)釋放 ---------*/unique_ptr<Test[]> ptr5(new Test[3]);//在c++11中shared_ptr不支持下面的寫法,c++11以后才支持的shared_ptr<Test[]> ptr6(new Test[3]);return 0; }

四,?弱引用的智能指針weak_ptr

?弱引用智能指針std::weak_ptr可以看做是shared_ptr的助手,它不管理shared_ptr內(nèi)部的指針。std::weak_ptr沒(méi)有重載操作符*和->,因?yàn)樗还蚕碇羔?#xff0c;不能操作資源,所以它的構(gòu)造不會(huì)增加引用計(jì)數(shù),析構(gòu)也不會(huì)減少引用計(jì)數(shù),它的主要作用就是作為一個(gè)旁觀者監(jiān)視shared_ptr中管理的資源是否存在。

?1 初始化

#include <iostream> #include <memory> using namespace std;int main() {shared_ptr<int> sp(new int);weak_ptr<int> wp1;weak_ptr<int> wp2(wp1);weak_ptr<int> wp3(sp);weak_ptr<int> wp4;wp4 = sp;weak_ptr<int> wp5;wp5 = wp3;return 0; }
  • weak_ptr<int> wp1;構(gòu)造了一個(gè)空weak_ptr對(duì)象
  • weak_ptr<int> wp2(wp1);通過(guò)一個(gè)空weak_ptr對(duì)象構(gòu)造了另一個(gè)空weak_ptr對(duì)象
  • weak_ptr<int> wp3(sp);通過(guò)一個(gè)shared_ptr對(duì)象構(gòu)造了一個(gè)可用的weak_ptr實(shí)例對(duì)象
  • wp4 = sp;通過(guò)一個(gè)shared_ptr對(duì)象構(gòu)造了一個(gè)可用的weak_ptr實(shí)例對(duì)象(這是一個(gè)隱式類型轉(zhuǎn)換)
  • wp5 = wp3;通過(guò)一個(gè)weak_ptr對(duì)象構(gòu)造了一個(gè)可用的weak_ptr實(shí)例對(duì)象
    • ?通過(guò)調(diào)用std::weak_ptr類提供的use_count()方法可以獲得當(dāng)前所觀測(cè)資源的引用計(jì)數(shù)

    ?2.常用函數(shù)

  • ?通過(guò)調(diào)用std::weak_ptr類提供的expired()方法來(lái)判斷觀測(cè)的資源是否已經(jīng)被釋放
  • 通過(guò)調(diào)用std::weak_ptr類提供的lock()方法來(lái)獲取管理所監(jiān)測(cè)資源的shared_ptr對(duì)象
  • 通過(guò)調(diào)用std::weak_ptr類提供的reset()方法來(lái)清空對(duì)象,使其不監(jiān)測(cè)任何資源
    • 利用weak_ptr可以解決shared_ptr的一些問(wèn)題
  • ?返回管理this的shared_ptr
  • 解決循環(huán)引用問(wèn)題
  • 總結(jié)

    以上是生活随笔為你收集整理的c++11之智能指针的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。