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

C++智能指針weak_ptr創(chuàng)建和使用詳解

 更新時(shí)間:2026年03月24日 16:00:19   作者:TTTrees  
std::weak_ptr是C++標(biāo)準(zhǔn)庫中的一個(gè)智能指針類,用于解決std::shared_ptr可能引發(fā)的循環(huán)引用問題,本文介紹C++智能指針weak_ptr創(chuàng)建和使用,感興趣的朋友跟隨小編一起看看吧

std::weak_ptr 是 C++ 標(biāo)準(zhǔn)庫中的一個(gè)智能指針類,用于解決 std::shared_ptr 可能引發(fā)的循環(huán)引用問題。循環(huán)引用可能導(dǎo)致內(nèi)存泄漏,因?yàn)橐糜?jì)數(shù)無法降為零,從而無法釋放對象。

std::weak_ptr是一種弱引用,它允許你觀測由 std::shared_ptr 管理的對象,但不會(huì)增加對象的引用計(jì)數(shù)。換句話說,std::weak_ptr 不擁有所指向?qū)ο蟮乃袡?quán),因此不會(huì)影響對象的生命周期。當(dāng) std::shared_ptr 管理的對象被銷毀后,對應(yīng)的 std::weak_ptr 會(huì)自動(dòng)失效,指向空值。

weak_ptr 創(chuàng)建和使用

  1. 我們不會(huì)直接創(chuàng)建 weak_ptr 去管理動(dòng)態(tài)對象
  2. weak_ptr 只能通過 shared_ptr 對象創(chuàng)建
  3. weak_ptr 引用 shared_ptr 對象時(shí),并不會(huì)增加引用計(jì)數(shù)
  4. weak_ptr 不直接操作 shared_ptr 管理的對象,但允許間接操作 shared_ptr 管理的對象
#if 1
#include <iostream>
using namespace std;
class Person
{
public:
    Person(int, int)
    {
        cout << "構(gòu)造函數(shù)" << endl;
    }
    void show()
    {
        cout << "Person::show 函數(shù)" << endl;
    }
    ~Person()
    {
        cout << "析構(gòu)函數(shù)" << endl;
    }
};
void test()
{
    // weak_ptr 是對 shared_ptr 的輔助,其自身并不擁有資源所有權(quán)
    shared_ptr<Person> sp1 = make_shared<Person>(10, 20);
    // 通過拷貝 shared_ptr 對象創(chuàng)建 weak_ptr 對象
    weak_ptr<Person> wp1(sp1);
    // weak_ptr 使用時(shí),不能直接訪問對象成員
    // 必須使用 lock 方法返回一個(gè) shared_ptr 對象(會(huì)增加引用)
    if (wp1.expired())
    {
        return;
    }
    auto sp2 = wp1.lock();
    sp2->show();
    // 可以將 shared_ptr 賦值給 weak_ptr 對象
    weak_ptr<Person> wp2;
    wp2 = sp1;
    // weak_ptr 相當(dāng)于一個(gè)不增加引用的 shared_ptr
    cout << "sp1:" << sp1.use_count() << endl;
    cout << "sp2:" << sp2.use_count() << endl;
    cout << "wp1:" << wp1.use_count() << endl;
    cout << "wp2:" << wp2.use_count() << endl;
}
int main()
{
    test();
    return 0;
}
#endif
構(gòu)造函數(shù)
Person::show 函數(shù)
sp1:2
sp2:2
wp1:2
wp2:2
析構(gòu)函數(shù)

shared_ptr 引用計(jì)數(shù)的缺陷

shared_ptr 以引用計(jì)數(shù)機(jī)制實(shí)現(xiàn)了對象共享,但是,引用計(jì)數(shù)機(jī)制本身存在一個(gè)自身難以解決的問題:循環(huán)引用

#if 1
#include <iostream>
using namespace std;
// 雙向鏈表節(jié)點(diǎn)
class LinkNode
{
public:
    LinkNode(int value)
    {
        cout << "LinkNode 構(gòu)造函數(shù)" << endl;
        data = value;
    }
    ~LinkNode()
    {
        cout << "LinkNode 析構(gòu)函數(shù)" << endl;
    }
public:
    int data;
    shared_ptr<LinkNode> prev;
    shared_ptr<LinkNode> next;
};
void test()
{
    // 創(chuàng)建兩個(gè)鏈表節(jié)點(diǎn)
    shared_ptr<LinkNode> node1(new LinkNode(10));
    shared_ptr<LinkNode> node2(new LinkNode(20));
    // 建立節(jié)點(diǎn)之間的關(guān)系
    node1->next = node2;
    node2->prev = node1;
}
int main()
{
    test();
    return 0;
}
#endif

我們對鏈表節(jié)點(diǎn)使用 shared_ptr 進(jìn)行了管理,防止出現(xiàn)忘記釋放而導(dǎo)致的內(nèi)存泄漏。但是,通過程序運(yùn)行的結(jié)果看到,兩個(gè) LinkNode 只調(diào)用了構(gòu)造函數(shù),并沒有調(diào)用析構(gòu)函數(shù),出現(xiàn)了內(nèi)存泄漏產(chǎn)生。

這是由于什么原因?qū)е碌哪兀?/p>

  1. 由于循環(huán)引用,導(dǎo)致兩個(gè) LinkNode 關(guān)聯(lián)的引用計(jì)數(shù)為 2
  2. 當(dāng) test 函數(shù)生命周期結(jié)束,node1 和 node2 的析構(gòu)函數(shù)調(diào)用,兩個(gè) LinkNode 對象引用計(jì)數(shù) -1,引用計(jì)數(shù)為 1
  3. 只有當(dāng) LinkNode 實(shí)際被銷毀時(shí),才會(huì)調(diào)用 prev 和 next 的析構(gòu)函數(shù)。

第 2、3 點(diǎn)是一對矛盾的存在:

  1. 只有 prev 和 next 被銷毀,LinkNode 才會(huì)被真正釋放
  2. 只有兩個(gè) LinkNode 被釋放,prev 和 next 才會(huì)被銷毀

weak_ptr 使用示例

當(dāng)一個(gè)對象持有對另一個(gè)對象的引用,而后者又持有對前者的引用時(shí),就會(huì)產(chǎn)生循環(huán)引用。所以,要打破這種循環(huán)的話,可以使用在發(fā)生循環(huán)引用的地方使用弱引用。

#if 1
#include <iostream>
using namespace std;
// 雙向鏈表節(jié)點(diǎn)
class LinkNode
{
public:
    LinkNode(int value)
    {
        cout << "LinkNode 構(gòu)造函數(shù)" << endl;
        data = value;
    }
    ~LinkNode()
    {
        cout << "LinkNode 析構(gòu)函數(shù)" << endl;
    }
public:
    int data;
    // 使用 weak_ptr 代替 shared_ptr
    weak_ptr<LinkNode> prev;
    weak_ptr<LinkNode> next;
};
void test()
{
    // 創(chuàng)建兩個(gè)鏈表節(jié)點(diǎn)
    shared_ptr<LinkNode> node1(new LinkNode(10));
    shared_ptr<LinkNode> node2(new LinkNode(20));
    // 建立節(jié)點(diǎn)之間的關(guān)系
    node1->next = node2;
    node2->prev = node1;
}
int main()
{
    test();
    return 0;
}
#endif

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

相關(guān)文章

  • C++ 二叉樹的鏡像實(shí)例詳解

    C++ 二叉樹的鏡像實(shí)例詳解

    這篇文章主要介紹了C++ 二叉樹的鏡像實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • c++中拷貝構(gòu)造函數(shù)的參數(shù)類型必須是引用

    c++中拷貝構(gòu)造函數(shù)的參數(shù)類型必須是引用

    如果拷貝構(gòu)造函數(shù)中的參數(shù)不是一個(gè)引用,即形如CClass(const CClass c_class),那么就相當(dāng)于采用了傳值的方式(pass-by-value),而傳值的方式會(huì)調(diào)用該類的拷貝構(gòu)造函數(shù),從而造成無窮遞歸地調(diào)用拷貝構(gòu)造函數(shù)。因此拷貝構(gòu)造函數(shù)的參數(shù)必須是一個(gè)引用
    2013-07-07
  • C++使用map容器實(shí)現(xiàn)電子詞典

    C++使用map容器實(shí)現(xiàn)電子詞典

    這篇文章主要為大家詳細(xì)介紹了C++如何使用map容器實(shí)現(xiàn)電子詞典功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以參考一下
    2022-11-11
  • Opencv檢測多個(gè)圓形(霍夫圓檢測,輪廓面積篩選)

    Opencv檢測多個(gè)圓形(霍夫圓檢測,輪廓面積篩選)

    本文主要介紹了Opencv檢測多個(gè)圓形(霍夫圓檢測,輪廓面積篩選),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • boost.asio框架系列之socket編程

    boost.asio框架系列之socket編程

    這篇文章介紹了boost.asio框架系列之socket編程,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Qt解析XML的三種常見方法實(shí)現(xiàn)與比較

    Qt解析XML的三種常見方法實(shí)現(xiàn)與比較

    XML是一種可擴(kuò)展的標(biāo)記語言,用于存儲(chǔ)和傳輸結(jié)構(gòu)化數(shù)據(jù),廣泛應(yīng)用于配置、數(shù)據(jù)交換和Web服務(wù)等領(lǐng)域,本文主要介紹了Qt解析XML的三種常見方法實(shí)現(xiàn)和性能對比,需要的可以了解下
    2025-06-06
  • 最新評(píng)論

    尤溪县| 泌阳县| 海阳市| 海安县| 开封市| 喀喇| 邯郸市| 大庆市| 嘉义市| 民乐县| 疏勒县| 宁波市| 保山市| 利辛县| 宿松县| 全椒县| 南澳县| 安化县| 女性| 玛纳斯县| 中山市| 龙海市| 江门市| 蒙阴县| 临沂市| 礼泉县| 昆山市| 宁强县| 达州市| 临夏县| 油尖旺区| 曲麻莱县| 千阳县| 苏州市| 西林县| 屯留县| 婺源县| 洪湖市| 滕州市| 南城县| 密山市|