91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++Smart?Pointer智能指針怎么用

發布時間:2022-03-14 13:32:49 來源:億速云 閱讀:302 作者:iii 欄目:開發技術

這篇文章主要講解了“C++Smart Pointer智能指針怎么用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++Smart Pointer智能指針怎么用”吧!

    一、為啥使用智能指針呢

    標準庫中的智能指針:
    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),就能防止內存泄漏。

    C++Smart?Pointer智能指針怎么用

    智能指針主要用于管理在堆上分配的內存,它將普通的指針封裝為一個棧對象。當棧對象的生存周期結束后,會在析構函數中釋放掉申請的內存,從而防止內存泄漏。

    • auto_ptr智能指針:(C++11出來前只有這種智能指針)當對象拷貝或者賦值后,前面的對象就懸空了。

    • unique_ptr智能指針:防止智能指針拷貝和復制。

    • shared_ptr智能指針:通過引用計數的方式來實現多個shared_ptr對象之間共享資源。

    • weak_ptr智能指針:可以從一個shared_ptr或另一個weak_ptr對象構造,它的構造和析構不會引起引用記數的增加或減少。

    注意:每一種智能指針都可以增加內存的引用計數。

    • 智能指針分為兩類:

      • 一種是可以使用多個智能指針管理同一塊內存區域,每增加一個智能指針,就會增加1次引用計數,

      • 另一類是不能使用多個智能指針管理同一塊內存區域,通俗來說,當智能指針2來管理這一塊內存時,原先管理這一塊內存的智能指針1只能釋放對這一塊指針的所有權(ownership)。

    • 按照這個分類標準,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;
    }

    C++Smart?Pointer智能指針怎么用

    二、shared_ptr智能指針

    shared_ptr實現了共享擁有的概念,利用“引用計數”來控制堆上對象的生命周期。

    share_ptr的生命周期:

    C++Smart?Pointer智能指針怎么用

    原理:在初始化的時候引用計數設為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>類型。

    C++Smart?Pointer智能指針怎么用

    shared_ptr的其他成員函數:

    use_count()	//返回引用計數的個數
    unique()	//返回是否是獨占所有權(use_count是否為1)
    swap()		//交換兩個shared_ptr對象(即交換所擁有的對象,引用計數也隨之交換)
    reset()		//放棄內部對象的所有權或擁有對象的變更, 會引起原有對象的引用計數的減少

    三、unique_ptr智能指針

    注意unique_ptr是single ownership的,不能拷貝。其構造方式如下:

    C++Smart?Pointer智能指針怎么用

    unique_ptr的生命周期:

    C++Smart?Pointer智能指針怎么用

    四、weak_ptr智能指針

    C++Smart?Pointer智能指針怎么用

    五、智能指針怎么解決交叉引用,造成的內存泄漏

    結論:創建對象時使用shared_ptr強智能指針指向,其余情況都使用weak_ptr弱智能指針指向。

    5.1 交叉引用的栗子:

    當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;
    }

    C++Smart?Pointer智能指針怎么用

    而當主函數mainreturn返回后,對象A的引用計數減一變為1(aptr沒指向A對象了),B對象也是,引用計數不為0,即不能析構2個對象釋放內存,造成內存泄漏。

    5.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。

    C++Smart?Pointer智能指針怎么用

    六、智能指針的注意事項

    • 避免同一塊內存綁定到多個獨立創建的shared_ptr上,因此要不使用相同的內置指針初始化(或reset)多個智能指針,不要混合使用智能指針和普通指針,堅持只用智能指針。

    • 不delete get() 函數返回的指針,因為這樣操作后,shared_ptr并不知道它管理的內存被釋放了,會造成shared_ptr重復析構。

    • 不使用 get()函數初始化或(reset)另外的智能指針。

    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開銷更高)。

    感謝各位的閱讀,以上就是“C++Smart Pointer智能指針怎么用”的內容了,經過本文的學習后,相信大家對C++Smart Pointer智能指針怎么用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    平湖市| 馆陶县| 佳木斯市| 观塘区| 承德市| 二手房| 安国市| 香格里拉县| 平安县| 天等县| 绥滨县| 高雄市| 井冈山市| 辽阳县| 城口县| 武宁县| 汉中市| 黑龙江省| 独山县| 南皮县| 顺昌县| 阿坝县| 土默特右旗| 连州市| 玉田县| 长子县| 濉溪县| 兰溪市| 玉环县| 南陵县| 柳林县| 新巴尔虎左旗| 宜兴市| 当涂县| 阳泉市| 香港| 昌宁县| 连城县| 民乐县| 古蔺县| 阿拉善左旗|