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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++11之智能指针

發布時間:2024/3/26 c/c++ 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++11之智能指针 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

一,什么是智能指針

二,共享的智能指針shared_ptr

1. shared_ptr的初始化

3.?指定刪除器

?三,獨占的智能指針unique_ptr

?1. 初始化

?2. 刪除器

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

?1 初始化

?2.常用函數


前言:面試的時候被問到智能指針了,答的很糟糕,這幾天重新學習了智能指針。下面是我對c++智能指針的理解與總結,希望能幫到大家,同時提升自己。

一,什么是智能指針

在C++中沒有垃圾回收機制,必須自己釋放分配的內存,否則就會造成內存泄露。解決這個問題最有效的方法是使用智能指針(smart pointer)。智能指針是存儲指向動態分配(堆)對象指針的類,用于生存期的控制,能夠確保在離開指針所在作用域時,自動地銷毀動態分配的對象,防止內存泄露。智能指針的核心實現技術是引用計數,每使用它一次,內部引用計數加1,每析構一次內部的引用計數減1,減為0時,刪除所指向的堆內存。

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

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

  • std::shared_ptr:共享的智能指針
  • std::unique_ptr:獨占的智能指針
  • std::weak_ptr:弱引用的智能指針,它不共享指針,不能操作資源,是用來監視shared_ptr的。
  • ?下面對他們分別進行分析

二,共享的智能指針shared_ptr

  • 首先了解一下基本概念,再看代碼,會學的很快

1. shared_ptr的初始化

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

2.獲取原始指針

?對應基礎數據類型來說,通過操作智能指針和操作智能指針管理的內存效果是一樣的,可以直接完成數據的讀寫。但是如果共享智能指針管理的是一個對象,那么就需要取出原始內存的地址再操作,可以調用共享智能指針類提供的get()方法得到原始地址

3.?指定刪除器

?當智能指針管理的內存對應的引用計數變為0的時候,這塊內存就會被智能指針析構掉了。另外,我們在初始化智能指針的時候也可以自己指定刪除動作,這個刪除操作對應的函數被稱之為刪除器這個刪除器函數本質是一個回調函數,我們只需要進行實現,其調用是由智能指針完成的。

  • ?上面三個基本知識點了解以后就可以輕松的閱讀代碼了(代碼注釋都非常的詳細哦!)
#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.通過構造函數初始化shared_ptr<int> ptr1(new int(3));cout << "ptr1管理的內存引用計數: " << ptr1.use_count() << endl;//2.通過移動和拷貝構造函數初始化shared_ptr<int> ptr2 = move(ptr1);cout << "ptr1管理的內存引用計數: " << ptr1.use_count() << endl;cout << "ptr2管理的內存引用計數: " << ptr2.use_count() << endl;shared_ptr<int> ptr3 = ptr2;cout << "ptr2管理的內存引用計數: " << ptr2.use_count() << endl;cout << "ptr3管理的內存引用計數: " << ptr3.use_count() << endl;//3.通過 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.通過reset初始化ptr6.reset(); //重置ptr6, ptr6的引用基數為0cout << "ptr6管理的內存引用計數: " << ptr6.use_count() << endl;ptr5.reset(new Test("hello"));cout << "ptr5管理的內存引用計數: " << 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.簡單舉例shared_ptr<Test> ppp(new Test(100), [](Test* t) {//釋放內存cout << "Test對象的內存被釋放了......." << endl;delete t;});printf("----------------------------------------------------------------------\n");2.如果是數組類型的地址,就需要自己寫指定刪除器,否則內存無法全部釋放//shared_ptr<Test> p1(new Test[5], [](Test* t) {// delete[]t;// });//3.也可以使用c++給我們提供的 默認刪除器函數(函數模板)shared_ptr<Test> p2(new Test[3], default_delete<Test[]>());//4.c++11以后可以這樣寫 也可以自動釋放內存shared_ptr<Test[]> p3(new Test[3]);return 0; }

?另外,我們還可以自己封裝一個函數模板make_shared_array方法來讓shared_ptr支持數組,代碼如下:

#include <iostream> #include <memory> #include <string> using namespace std;//有了這個函數模板,我們就不用自己去釋放數組類型的地址了 template <typename T> shared_ptr<T> make_share_array(size_t size) {//返回匿名對象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; }

?三,獨占的智能指針unique_ptr

  • 首先了解一下基本概念,再看代碼,會學的很快

?1. 初始化

std::unique_ptr是一個獨占型的智能指針,它不允許其他的智能指針共享其內部的指針,可以通過它的構造函數初始化一個獨占智能指針對象,但是不允許通過賦值將一個unique_ptr賦值給另一個unique_ptr。

?2. 刪除器

?unique_ptr指定刪除器和shared_ptr指定刪除器是有區別的,unique_ptr指定刪除器的時候需要確定刪除器的類型,所以不能像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.通過構造函數初始化unique_ptr<int> ptr1(new int(3));//2.通過移動函數初始化unique_ptr<int> ptr2 = move(ptr1);//.通過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.函數指針類型//using ptrFunc = void(*)(Test*);//unique_ptr<Test, ptrFunc> ptr4(new Test("hello"), [](Test* t) {// cout << "-----------------------" << endl;// delete t;// });//2.仿函數類型(利用可調用對象包裝器)unique_ptr<Test, function<void(Test*)>> ptr4(new Test("hello"), [](Test* t) {cout << "-----------------------" << endl;delete t;});/*---------- 四,獨占(共享)的智能指針可以管理數組類型的地址,能夠自動釋放 ---------*/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內部的指針。std::weak_ptr沒有重載操作符*和->,因為它不共享指針,不能操作資源,所以它的構造不會增加引用計數,析構也不會減少引用計數,它的主要作用就是作為一個旁觀者監視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;構造了一個空weak_ptr對象
  • weak_ptr<int> wp2(wp1);通過一個空weak_ptr對象構造了另一個空weak_ptr對象
  • weak_ptr<int> wp3(sp);通過一個shared_ptr對象構造了一個可用的weak_ptr實例對象
  • wp4 = sp;通過一個shared_ptr對象構造了一個可用的weak_ptr實例對象(這是一個隱式類型轉換)
  • wp5 = wp3;通過一個weak_ptr對象構造了一個可用的weak_ptr實例對象
    • ?通過調用std::weak_ptr類提供的use_count()方法可以獲得當前所觀測資源的引用計數

    ?2.常用函數

  • ?通過調用std::weak_ptr類提供的expired()方法來判斷觀測的資源是否已經被釋放
  • 通過調用std::weak_ptr類提供的lock()方法來獲取管理所監測資源的shared_ptr對象
  • 通過調用std::weak_ptr類提供的reset()方法來清空對象,使其不監測任何資源
    • 利用weak_ptr可以解決shared_ptr的一些問題
  • ?返回管理this的shared_ptr
  • 解決循環引用問題
  • 總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。