最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中智能指針最常用的shared_ptr和unique_ptr

 更新時(shí)間:2022年08月23日 08:35:50   作者:TTOR  
C++中的智能指針最常用的是shared_ptr和unique_ptr,C++新手最常問(wèn)的問(wèn)題是我從一個(gè)函數(shù)中拿到unique_ptr,但要轉(zhuǎn)成shared_ptr才能使用,要怎么轉(zhuǎn)換?同理是否能將shared_ptr轉(zhuǎn)換成unique_ptr,面對(duì)這些問(wèn)題,跟隨小編一起看看吧

shared_ptr

基本用法: 可以通過(guò)構(gòu)造函數(shù), make_shared<T>輔助函數(shù)和reset()方法來(lái)初始化shared_ptr

1. 初始化方法

    shared_ptr<int> p1(new int(1));
    shared_ptr<int> p2 = p1;
    shared_ptr<int> p3;
    p3.reset(new int(1));
    shared_ptr<int> p4 = make_shared<int>(int(5));

優(yōu)先使用make_shared來(lái)構(gòu)造, 更加高效

不能用一個(gè)原始指針直接賦值智能指針, 以下方式是錯(cuò)誤的

shared_ptr<int> p5=new int(1); //error

2.獲取智能指針的原始指針: 通過(guò)get方法

    shared_ptr<int> ptr = make_shared<int>(int(5));
    int *p=ptr.get();

3.指定刪除器:自定義指針?shù)N毀方式

void ptr_deleter(const int*p)
{
    delete p;
}
shared_ptr<int> p(new int, ptr_deleter);

第二個(gè)參數(shù)指定刪除器(一個(gè)可調(diào)用對(duì)象, 其中參數(shù)為該類(lèi)型的指針, 如上面為int*)

當(dāng)shared_ptr引用計(jì)數(shù)為0時(shí), 調(diào)用傳入的而不是默認(rèn)的刪除器來(lái)釋放對(duì)象的內(nèi)存

當(dāng)用shared_ptr管理動(dòng)態(tài)數(shù)組時(shí), 需要指定刪除器, 因?yàn)閟hared_ptr默認(rèn)刪除器不支持?jǐn)?shù)組對(duì)象

如下使用lambda表達(dá)式作為刪除器

shared_ptr<int> p(new int[10],[](int*p){delete []p;});

通過(guò)default_delete作為刪除器, 同時(shí)封裝一個(gè)make_shared_array函數(shù)來(lái)支持?jǐn)?shù)組

template<typename T>
shared_ptr<T> make_shared_array(int size)
{
    return shared_ptr<T>(new T[size],default_delete<T[]>());
}

(自測(cè))貌似這樣也支持?jǐn)?shù)組

shared_ptr<int[]> ptr(new int[10]);

使用shared_ptr注意

(1)不要用一個(gè)原始指針初始化多個(gè)shared_ptr

    int *ptr = new int;
    shared_ptr<int> p1(ptr);
    shared_ptr<int> p2(ptr);  //錯(cuò)誤

(2)不要在函數(shù)實(shí)參中創(chuàng)建shared_ptr

function(shared_ptr<int>(new int),g());

參數(shù)的計(jì)算順序可能沒(méi)有固定順序, 若是new int后執(zhí)行g(shù)()拋出異常, 則shared_ptr還沒(méi)有創(chuàng)建, 則new int內(nèi)存泄漏了

(3)不要用this指針構(gòu)造shared_ptr作為返回值

class A
{
public:
    shared_ptr<A> get_self()
    {
        return shared_ptr<A>(this);
    }
    ~A()
    {
        cout << ("destructor") << endl;
    }
};
int main()
{
    shared_ptr<A> p1(new A);
    shared_ptr<A> p2 = p1->get_self();
    return 0;
}

destructor

destructor

以上代碼p1和p2相當(dāng)于同一個(gè)new A初始化, 會(huì)shared_ptr銷(xiāo)毀時(shí), 會(huì)重復(fù)析構(gòu)

正確做法:

讓該類(lèi)繼承enable_shared_from_this<>, 同時(shí)調(diào)用shared_from_this()返回

class A :public enable_shared_from_this<A>    //繼承
{
public:
    shared_ptr<A> get_self()
    {
        return shared_from_this();            //調(diào)用該函數(shù)
    }
    ~A()
    {
        cout << ("destructor") << endl;
    }
};
int main()
{
    shared_ptr<A> p1(new A);
    shared_ptr<A> p2 = p1->get_self();
    return 0;
}

destructor

只要用shared_ptr, 調(diào)用的成員函數(shù)里都不能使用this構(gòu)造, 否則都會(huì)出錯(cuò)

class A
{
public:
    void test()
    {
        shared_ptr<A>(this); //錯(cuò)誤
    }
    ~A()
    {
        cout<<(  "destructor"  )<<endl;
    }
};
shared_ptr<A> p(new A);
p->test()

另外, 不要在構(gòu)造函數(shù)里使用shared_from_this

(4)避免循環(huán)引用

以下代碼會(huì)由于循環(huán)引用, 引用計(jì)數(shù)值都為1, 導(dǎo)致兩個(gè)指針都不會(huì)析構(gòu)

class A;
class B;
class A
{
public:
    shared_ptr<B> b_ptr;
    ~A()
    {
        cout << ("A destructor") << endl;
    }
};
class B
{
public:
    shared_ptr<A> a_ptr;
    ~B()
    {
        cout << ("B destructor") << endl;
    }
};
int main()
{
    shared_ptr<A> a_p(new A);
    shared_ptr<B> b_p(new B);
    a_p->b_ptr=b_p;
    b_p->a_ptr=a_p;
}

//沒(méi)有輸出

unique_ptr

unique_ptr不允許復(fù)制, 不允許其他的智能指針共享其內(nèi)部的指針, 但可以轉(zhuǎn)移

    unique_ptr<int> ptr(new int);
   // unique_ptr<int> ptr2=ptr;    error 不可以賦值
    unique_ptr<int> ptr3=move(ptr); //用move進(jìn)行轉(zhuǎn)移
    assert(ptr!=nullptr); //轉(zhuǎn)移后ptr為nullptr

自定義make_unique函數(shù)且讓其支持定長(zhǎng)數(shù)組

思路

不是數(shù)組, 返回unique_ptr<T>

是數(shù)組且非定長(zhǎng)數(shù)組, 返回unique_ptr<T>, 即不應(yīng)該調(diào)用make_unique<T[10]>(10)而是make_unique<T[]>(10)

最后過(guò)濾掉該定長(zhǎng)數(shù)組(函數(shù)聲明為delete)

// !is_array_v確定不是數(shù)組, 返回unique_ptr<T>
template<typename T,typename ...Args>
enable_if_t<!is_array_v<T>,unique_ptr<T>> make_unique_(Args&&...args)
{
    return unique_ptr<T>( new T(forward<Args>(args)...));
}
//定長(zhǎng)數(shù)組如T[10],  不應(yīng)該調(diào)用make_unique<T[10]>(10);而是make_unique<T[]>(10);
// is_array_v確定是數(shù)組且!extent_v<T>確定非定長(zhǎng)數(shù)組, 返回unique_ptr<T>
template<typename T,typename ...Args>
enable_if_t<is_array_v<T>&&!extent_v<T>,unique_ptr<T>> make_unique_(size_t size)
{
    using U=remove_extent_t<T>;
    return unique_ptr<T>( new U[size]);
}
//否之過(guò)濾掉該定長(zhǎng)數(shù)組
template<typename T,typename ...Args>
enable_if_t<extent_v<T>,void> make_unique_(Args&&...)=delete;
    unique_ptr<int> ptr= make_unique_<int>(10);
    unique_ptr<int[]> ptr1= make_unique_<int[]>(10);

不過(guò)unique_ptr本身也支持?jǐn)?shù)組, shared_ptr自測(cè)也支持, 如下

    unique_ptr<A[]> ptr1(new A[10]);
    shared_ptr<A[]> ptr2(new A[10]);

unique_ptr也支持刪除器, 但和shared_ptr有區(qū)別, 要指定刪除器類(lèi)型

    shared_ptr<A> p1(new A[10],[](A*p){delete []p;});
   // unique_ptr<A> p2(new A[10],[](A*p){delete []p;}); 錯(cuò)誤
    unique_ptr<A,void(*)(A*)> p2(new A[10],[](A*p){delete []p;}); //正確

如果希望lambda刪除器捕獲變量, 則需要用function包裝

    unique_ptr<A,void(*)(A*)> p1(new A[10],[&](A*p){delete []p;});       //錯(cuò)誤
    unique_ptr<A,function<void(A*)>> p2(new A[10],[&](A*p){delete []p;}); //正確

到此這篇關(guān)于C++中智能指針最常用的shared_ptr和unique_ptr的文章就介紹到這了,更多相關(guān)C++ shared_ptr和unique_ptr內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言結(jié)構(gòu)體數(shù)組常用的三種賦值方法(包含字符串)

    C語(yǔ)言結(jié)構(gòu)體數(shù)組常用的三種賦值方法(包含字符串)

    C語(yǔ)言只有在定義字符數(shù)組的時(shí)候才能用“=”來(lái)初始化變量,其它情況下是不能直接用“=”來(lái)為字符數(shù)組賦值的,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言結(jié)構(gòu)體數(shù)組常用的三種賦值方法,需要的朋友可以參考下
    2022-06-06
  • Qt之QTimer使用及技巧小結(jié)

    Qt之QTimer使用及技巧小結(jié)

    QTimer是Qt中的定時(shí)器類(lèi),用于執(zhí)行定時(shí)操作,如在一段時(shí)間間隔后觸發(fā)某個(gè)槽函數(shù)或執(zhí)行特定的代碼,下面就來(lái)介紹一下Qt之QTimer使用及技巧小結(jié),感興趣的可以了解一下
    2023-10-10
  • Qt串口通信開(kāi)發(fā)之QSerialPort模塊Qt串口通信接收數(shù)據(jù)不完整的解決方法

    Qt串口通信開(kāi)發(fā)之QSerialPort模塊Qt串口通信接收數(shù)據(jù)不完整的解決方法

    這篇文章主要介紹了Qt串口通信開(kāi)發(fā)之QSerialPort模塊Qt串口通信接收數(shù)據(jù)不完整的解決方法,需要的朋友可以參考下
    2020-03-03
  • 詳解C++ 動(dòng)態(tài)庫(kù)導(dǎo)出函數(shù)名亂碼及解決

    詳解C++ 動(dòng)態(tài)庫(kù)導(dǎo)出函數(shù)名亂碼及解決

    這篇文章主要介紹了C++ 動(dòng)態(tài)庫(kù)導(dǎo)出函數(shù)名亂碼及解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • C++中auto關(guān)鍵字的使用

    C++中auto關(guān)鍵字的使用

    本文主要介紹了C++中auto關(guān)鍵字的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • C++?OpenCV實(shí)現(xiàn)白平衡之完美反射算法

    C++?OpenCV實(shí)現(xiàn)白平衡之完美反射算法

    完美反射算法是白平衡各種算法中較常見(jiàn)的一種,比灰度世界算法更優(yōu)。本文將利用C++和OpenCV實(shí)現(xiàn)白平衡中的完美反射算法,需要的可以參考一下
    2022-05-05
  • c語(yǔ)言中用字符串?dāng)?shù)組顯示菜單的解決方法

    c語(yǔ)言中用字符串?dāng)?shù)組顯示菜單的解決方法

    本篇文章是對(duì)c語(yǔ)言中用字符串?dāng)?shù)組顯示菜單的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 詳解C++中的自動(dòng)存儲(chǔ)

    詳解C++中的自動(dòng)存儲(chǔ)

    這篇文章主要介紹了詳解C++中的自動(dòng)存儲(chǔ),幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下
    2020-09-09
  • 數(shù)據(jù)結(jié)構(gòu) 雙機(jī)調(diào)度問(wèn)題的實(shí)例詳解

    數(shù)據(jù)結(jié)構(gòu) 雙機(jī)調(diào)度問(wèn)題的實(shí)例詳解

    這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu) 雙機(jī)調(diào)度問(wèn)題的實(shí)例詳解的相關(guān)資料,雙機(jī)調(diào)度問(wèn)題,又稱獨(dú)立任務(wù)最優(yōu)調(diào)度:用兩臺(tái)處理機(jī)A和B處理n個(gè)作業(yè)的實(shí)例,需要的朋友可以參考下
    2017-08-08
  • C語(yǔ)言指針的圖文詳解

    C語(yǔ)言指針的圖文詳解

    這篇文章主要為大家介紹了C語(yǔ)言指針,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01

最新評(píng)論

宁夏| 靖江市| 鸡泽县| 临泽县| 陆良县| 武平县| 眉山市| 伊金霍洛旗| 五莲县| 定西市| 教育| 寻乌县| 军事| 伊通| 三河市| 松江区| 连城县| 松桃| 陇南市| 郁南县| 淮北市| 海城市| 弥勒县| 新安县| 元朗区| 新化县| 定南县| 肥城市| 仪陇县| 庆云县| 镇坪县| 吴川市| 金沙县| 肇东市| 剑阁县| 邢台县| 伊金霍洛旗| 册亨县| 临海市| 兖州市| 阳朔县|