<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
標準庫中的智慧指標: std::auto_ptr --single ownership (C++98中出現,缺陷較多,被摒棄) std::unique_ptr --single ownership (C++11替代std::auto_ptr,用於單執行緒) std::shared_ptr --shared ownership (C++11,用於多執行緒) std::weak_ptr --temp/no ownership (C++11) Introduced in C++ 11 Defined in <memory> header.
首先看一個下面的栗子,左邊是木有使用智慧指標的情況,當執行foo()
函數,其中的e
指標會在bar(e)
時傳入bar
函數,但是在bar
函數結束後沒有人為delete e
時,就會導致記憶體漏失;但是在右邊的栗子中,使用了unique_ptr
智慧指標(single ownership),就能防止記憶體漏失。
智慧指標主要用於管理在堆上分配的記憶體,它將普通的指標封裝為一個棧物件。當棧物件的生存週期結束後,會在解構函式中釋放掉申請的記憶體,從而防止記憶體漏失。
auto_ptr
智慧指標:(C++11出來前只有這種智慧指標)當物件拷貝或者賦值後,前面的物件就懸空了。unique_ptr
智慧指標:防止智慧指標拷貝和複製。shared_ptr
智慧指標:通過參照計數的方式來實現多個shared_ptr
物件之間共用資源。weak_ptr
智慧指標:可以從一個shared_ptr
或另一個weak_ptr
物件構造,它的構造和解構不會引起參照記數的增加或減少。注意:每一種智慧指標都可以增加記憶體的參照計數。
auto_ptr
unique_ptr
weak_ptr
屬於後者,shared_ptr
屬於前者。對shared_ptr
進行初始化時不能將一個普通指標直接賦值給智慧指標,因為一個是指標,一個是類。可以通過make_shared
函數或者通過建構函式傳入普通指標。並可以通過get
函數獲得普通指標。
#include <string> #include <memory> using namespace std; class report { private: string str; public: report(const string s):str(s) //構造方法 { cout<<"1 report Object has been build!"<<endl; } ~report() { cout<<"3 report Object deleted!"<<endl; } void talk() { cout<<str<<endl; } }; int main() { string talk="2 hello,this is a test!"; { auto_ptr<report> ptr(new report(talk)); ptr->talk(); } { shared_ptr<report> ptr(new report(talk)); ptr->talk(); } { unique_ptr<report> ptr(new report(talk)); ptr->talk(); } return 0; }
shared_ptr
實現了共用擁有的概念,利用“參照計數”來控制堆上物件的生命週期。
share_ptr
的生命週期:
原理:在初始化的時候參照計數設為1,每當被拷貝或者賦值的時候參照計數+1,解構的時候參照計數-1,直到參照計數被減到0,那麼就可以delete掉物件的指標了。他的構造方式主要有以下三種:
shared_ptr<Object> ptr; shared_ptr<Object> ptr(new Object); shared_ptr<Object> ptr(new Object, [=](Object *){ //回收資源時呼叫的函數 }); auto ptr = make_shared<Object>(args);
shared_ptr
管理的堆上物件的指標,所以參照計數為0,後期可以通過reset()
成員函數來指定其管理的堆上物件的指標,reset()
之後參照計數設為1。weak_ptr
)。shared_ptr
在解構自己所儲存的堆上物件的指標時(即參照計數為0時)所要呼叫的函數,這說明我們可以自定義特定物件的特定解構方式。同樣的,reset()
成員函數也可以指定解構時呼叫的指定函數。shared_ptr
的方式(最安全):auto ptr = make_shared<Object>(args);
上面第四種方法,使用標準庫裡邊的
make_shared<>()
模板函數。該函數會呼叫模板類的構造方法,範例化一個堆上物件,然後將儲存了該物件指標的shared_ptr
返回。引數是該類建構函式的引數,所以使用make_shared<>()
就好像單純地在構造該類物件一樣。auto
是C++11的一個關鍵字,可以在編譯期間自動推算變數的型別,在這裡就是shared_ptr<Object>
型別。
shared_ptr
的其他成員函數:
use_count() //返回參照計數的個數 unique() //返回是否是獨佔所有權(use_count是否為1) swap() //交換兩個shared_ptr物件(即交換所擁有的物件,參照計數也隨之交換) reset() //放棄內部物件的所有權或擁有物件的變更, 會引起原有物件的參照計數的減少
注意unique_ptr
是single ownership的,不能拷貝。其構造方式如下:
unique_ptr
的生命週期:
結論:建立物件時使用shared_ptr
強智慧指標指向,其餘情況都使用weak_ptr
弱智慧指標指向。
當A類中有一個指向B類的shared_ptr
強型別智慧指標,B類中也有一個指向A類的shared_ptr
強型別智慧指標。
main
函數執行後有兩個強智慧指標指向了物件A,物件A的參照計數為2,B類也是:
#include <iostream> #include <memory> using namespace std; class B; class A{ public: shared_ptr<B> _bptr; }; class B{ public: shared_ptr<A> _aptr; }; int main(){ shared_ptr<A> aptr(new A()); shared_ptr<B> bptr(new B()); aptr->_bptr = bptr; bptr->_aptr = aptr; return 0; }
而當主函數main
的return
返回後,物件A
的參照計數減一變為1(aptr
沒指向A
物件了),B
物件也是,參照計數不為0,即不能解構2個物件釋放記憶體,造成記憶體漏失。
將類A和類B中的shared_ptr
強智慧指標都換成weak_ptr
弱智慧指標;
class A{ public: weak_ptr<B> _bptr; }; class B{ public: weak_ptr<A> _aptr; };
weak_ptr
弱智慧指標,雖然有參照計數,但實際上它並不增加計數,而是隻觀察物件的參照計數。所以此時物件A的參照計數只為1,物件B的參照計數也只為1。
shared_ptr
並不知道它管理的記憶體被釋放了,會造成shared_ptr重複解構。shared_ptr<int> p = make_share<int> (42); int *q = p.get(); { shared_ptr<int>(q); } // 程式塊結束,q被銷燬,指向的記憶體被釋放。 int foo = *p; // 出錯,p指向的記憶體已經被q釋放,這是用get() 初始化另外的智慧指標惹得禍。 // 請記住,永遠不要用get初始化另外一個智慧指標。
能使用unique_ptr
時就不要使用share_ptr
指標(後者需要保證執行緒安全,所以在賦值or銷燬時overhead開銷更高)。
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45