關於C++1X中智能指針std::shared_ptr的使用示例

吐槽一下,現在CSDN的編輯器真實太大媽爛!
本實例演示了
std::shared_ptr<T>的初始化的集中方法,
使用上不能使用棧上對象初始化
刪除器的使用
函數傳參的使用
等使用方法
// smart-ptr.cpp: 定義控制檯應用程序的入口點。
//


#include "stdafx.h"
#include <iostream>
#include <memory>
using namespace std;


class cls
{
public:
    cls()
    {
        printf("cls(), this=%x\r\n", this);
    }
    ~cls()
    {
        printf("~cls(), this=%x\r\n", this);
    }
    cls(const cls & a)
    {
        printf("cls(const cls & a), this=%x\r\n",this);
    }
    cls(cls && a)
    {
        printf("cls(cls && a), this=%x\r\n", this);
    }
    cls& operator=(const cls & a)
    {
        printf("cls& operator=(const cls &a), this=%x\r\n", this);
    }
    cls& operator=(const cls && a)
    {
        printf("cls& operator=(const cls && a), this=%x\r\n", this);
    }
};


void func_delete(cls *x)
{
    printf("in function deleter\r\n");
    delete x;
}


class functor
{
public:
    functor()
    {
        printf("functor(), this=%x\r\n", this);
    }
    ~functor()
    {
        printf("~functor(), this=%x\r\n", this);
    }
    functor(const functor & a)
    {
        printf("functor(const functor & a), this=%x\r\n", this);
    }
    functor(functor && a)
    {
        printf("functor(functor && a), this=%x\r\n", this);
    }
    functor& operator=(const functor & a)
    {
        printf("functor& operator=(const functor &a), this=%x\r\n", this);
    }
    functor& operator=(const functor && a)
    {
        printf("functor& operator=(const functor && a), this=%x\r\n", this);
    }
    void operator()(cls *x)
    {
        printf("in functor deleter, this=%x\r\n", this);
        delete x;
    }
};


void func(std::shared_ptr<cls> *ptra)
{
    printf("ptra.use_count()=%d\r\n", ptra->use_count());
}
int main(int argc, char **argv)
{
    if (1)
    {
        /*
        本函數演示將shared_ptr作爲函數參數時,shared_ptr的狀態和行爲模式變化。
        */
        cls *a = new cls();
        std::shared_ptr<cls> ptr(a, std::default_delete<cls>());
        func(&ptr);
    }
    if (0)
    {
        /*
        構建std::shared_ptr的幾種方法
        1、使用std::make_shared
        2、使用一個shared_ptr初始化另一個shared_ptr
        3、使用shared_ptr.reset()
        4、使用堆上的裸指針初始化shared_ptr


        從本實例也可以看出,在vs2017編譯的程序上,棧上對象的銷燬順序是與他們的聲明順序剛好相反。
        */
        cls a, *b = new cls(), *c = new cls();
        printf("&a=%x,b=%x,c=%x\r\n", &a, b, c);


        std::shared_ptr<cls> ptra = std::make_shared<cls>();//調用了a的無參構造函數
        std::shared_ptr<cls> ptrb = std::make_shared<cls>(a);//調用了a的拷貝構造函數
        std::shared_ptr<cls> ptra2(ptra);   //調用的是std::shared_ptr<T>的拷貝構造函數
        std::shared_ptr<cls> ptra3;     ptra3.reset(b);     //調用shared_ptr<T>.reset()方法
        std::shared_ptr<cls> ptra4(c);      //使用堆上的指針初始化std::shared_ptr


        printf("ptra.use_count()=%d\r\n", ptra.use_count());


        printf("ptra.get()=%x\r\n", ptra.get());
        printf("ptrb.get()=%x\r\n", ptrb.get());
        printf("ptra2.get()=%x\r\n", ptra2.get());
        printf("ptra3.get()=%x\r\n", ptra3.get());
        printf("ptra4.get()=%x\r\n", ptra4.get());
    }
    if (0)
    {
        /*
        這種寫法會引起程序假死,不管a是自定義類型還是基礎類型。
        當shared_ptr指向的指針內存被釋放掉之後,在執行shared_ptr的析構函數,就會假死。
        即://ERROR!!! 當將a託管給shared_ptr之後,a就不可以手動刪除。
        即:不能用棧上的對象去初始化std::shared_ptr。
        */
        cout << "--------------------------" << endl;
        cls a;
        std::shared_ptr<cls> ptra3(&a);
    }
    if (0)
    {
        /*
        智能指針會託管交給他的對象,當將a託管給shared_ptr之後,a就不可以手動刪除。
        */
        cout << "--------------------------" << endl;
        cls *a = new cls();
        std::shared_ptr<cls> ptra(a);
        printf("ptra.use_count()=%d\r\n", ptra.use_count());


        //delete a; a = nullptr;//ERROR!!! 


        printf("ptra.use_count()=%d\r\n", ptra.use_count());


        cls *pa = ptra.get();
        printf("*pa=%d\r\n", pa);
    }
    if (0)
    {
        /*
        本示例演示給std::shared_ptr<>設置刪除器
		1、默認刪除器
		2、lambda刪除器
		3、函數指針刪除器
		4、仿函數刪除器
        */
        cout << "--------------------------" << endl;
        cls *a = new cls();
        std::shared_ptr<cls> ptr(a, std::default_delete<cls>());


        cls *b = new cls();
        std::shared_ptr<cls> ptr2(b, [](cls *x)->void {
            printf("in lambda deleter\r\n");
            delete x;
        });


        cls *c = new cls();
        std::shared_ptr<cls> ptr3(c,func_delete);


        cls *d = new cls();
        std::shared_ptr<cls> ptr4(d, functor());
        std::shared_ptr<cls> ptr5(ptr4);


        /*
        一組可能的打印如下:注意一下,如果使用函數對象作爲析構器,要進行高達4此構造!
        --------------------------
        cls(), this=608100
        cls(), this=608130
        cls(), this=607ef0
        cls(), this=6081f0
        functor(), this=1ff67c
        functor(functor && a), this=1ff578
        functor(functor && a), this=1ff44c
        functor(functor && a), this=60d024
        ~functor(), this=1ff44c
        ~functor(), this=1ff578
        ~functor(), this=1ff67c
        in functor deleter, this=60d024
        ~cls(), this=6081f0
        ~functor(), this=60d024
        in function deleter
        ~cls(), this=607ef0
        in lambda deleter
        ~cls(), this=608130
        ~cls(), this=608100
        --------------------------
        */
    }


    cout << "--------------------------" << endl << endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章