偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

C++ 面試題:循環(huán)引用兩個(gè)節(jié)點(diǎn)相互引用,如何判斷哪個(gè)用 shared_ptr?哪個(gè)用 weak_ptr?

開發(fā)
通過分析對象生命周期控制權(quán),確定shared_ptr和weak_ptr的使用。始終確保至少有一條所有權(quán)路徑不形成閉環(huán)。

一、回顧循環(huán)引用問題

當(dāng)兩個(gè)對象通過 shared_ptr 相互引用時(shí),會(huì)產(chǎn)生循環(huán)引用問題,導(dǎo)致內(nèi)存泄漏。因?yàn)檫@兩個(gè)對象的引用計(jì)數(shù)永遠(yuǎn)不會(huì)變?yōu)?0,即使它們在程序的其他部分已經(jīng)不被使用了。

典型循環(huán)引用:

#include <memory>
#include <iostream>
usingnamespace std;

classB; // 前置聲明

classA {
public:
    shared_ptr<B> b_ptr;
    ~A() { cout << "A destroyed" << endl; }
};

classB {
public:
    shared_ptr<A> a_ptr;
    ~B() { cout << "B destroyed" << endl; }
};

voidtest(){
    shared_ptr<A> a = make_shared<A>();
    shared_ptr<B> b = make_shared<B>();
    a->b_ptr = b;
    b->a_ptr = a;
} 
// test結(jié)束時(shí),a和b的引用計(jì)數(shù)均為1,對象未銷毀

解決方案是打破這個(gè)循環(huán),通常是讓其中一個(gè)對象使用 weak_ptr 指向另一個(gè)對象,而另一個(gè)對象使用 shared_ptr。這里決定使用 shared_ptr 還是 weak_ptr 的關(guān)鍵在于所有權(quán)關(guān)系的分析。

二、所有權(quán)模型與指針選擇

1. 核心原則:所有權(quán)決定指針類型

所有權(quán)關(guān)系指一個(gè)對象對另一個(gè)對象生命周期的控制權(quán)。所有權(quán)持有者使用shared_ptr,非所有者使用weak_ptr。

示例:父子節(jié)點(diǎn)模型

class Child; 

classParent {
public:
    vector<shared_ptr<Child>> children;
    voidaddChild(shared_ptr<Child> child){
        children.push_back(child);
    }
    ~Parent() { cout << "Parent destroyed" << endl; }
};

classChild {
public:
    weak_ptr<Parent> parent; // 非擁有性引用
    explicitChild(shared_ptr<Parent> p) : parent(p) {}
    ~Child() { cout << "Child destroyed" << endl; }
};

voiddemo(){
    auto parent = make_shared<Parent>();
    auto child = make_shared<Child>(parent);
    parent->addChild(child);
}
// demo結(jié)束時(shí),parent引用計(jì)數(shù)歸零,觸發(fā)Child析構(gòu)

輸出結(jié)果:

Parent destroyed
Child destroyed

關(guān)鍵點(diǎn):Parent 擁有 Child,Child 僅引用 Parent。

2. 雙向鏈表的設(shè)計(jì)取舍

雙向鏈表中,節(jié)點(diǎn)間常需雙向引用。為避免循環(huán)引用,需明確主從關(guān)系。

示例:鏈表節(jié)點(diǎn)設(shè)計(jì)

class Node {
public:
    shared_ptr<Node> next; // 擁有下一個(gè)節(jié)點(diǎn)
    weak_ptr<Node> prev;   // 非擁有前驅(qū)節(jié)點(diǎn)
    int data;
    Node(int val) : data(val) {}
    ~Node() { cout << "Node " << data << " destroyed" << endl; }
};

voidbuildList(){
    auto node1 = make_shared<Node>(1);
    auto node2 = make_shared<Node>(2);
    node1->next = node2;
    node2->prev = node1;
}
// buildList結(jié)束時(shí),node1和node2的引用計(jì)數(shù)歸零

輸出結(jié)果:

Node 1 destroyed
Node 2 destroyed

設(shè)計(jì)邏輯:鏈表的構(gòu)建通常從前向后遍歷,故next持有所有權(quán),prev僅作反向引用。

三、復(fù)雜場景的決策策略

1. 多所有者場景

若多個(gè)對象共享某資源,需由頂層管理者持有shared_ptr,其余使用weak_ptr。

示例:緩存系統(tǒng)設(shè)計(jì)

#include <unordered_map>

classCacheManager;

classResource {
public:
    weak_ptr<CacheManager> manager;  // 弱引用管理器
};

classCacheManager : public enable_shared_from_this<CacheManager> {
public:
    voidaddResource(int id){
        resources[id] = make_shared<Resource>();
        resources[id]->manager = shared_from_this();  // 關(guān)鍵行
    }
};

說明:CacheManager擁有所有Resource,Resource通過weak_ptr反向引用管理器。

2. 無明確所有權(quán)場景

若對象間無明確從屬關(guān)系,需重新審視設(shè)計(jì)或使用雙向weak_ptr。

示例:聊天室和用戶

#include <memory>
#include <vector>
#include <iostream>
usingnamespace std;

classChatRoom;

classUser {
public:
    string name;
    vector<weak_ptr<ChatRoom>> rooms;  // 弱引用聊天室
};

classChatRoom {
public:
    string name;
    vector<weak_ptr<User>> users;  // 弱引用用戶
};

intmain(){
    auto alice = make_shared<User>("Alice");
    auto general = make_shared<ChatRoom>("General");
    return0;
}

說明:用戶(User) 可以加入多個(gè)聊天室,聊天室(ChatRoom) 包含多個(gè)用戶,但是他們互相并沒有所有權(quán)關(guān)系,所以使用雙向weak_ptr,用戶和聊天室的生命周期由外部系統(tǒng)管理!

四、實(shí)踐中的注意事項(xiàng)

1. weak_ptr 的安全訪問

使用weak_ptr時(shí)需通過lock()獲取shared_ptr,并檢查有效性。

void accessParent(shared_ptr<Child> child) {
    if (auto parent = child->parent.lock()) {
        cout << "Parent is alive: " << parent << endl;
    } else {
        cout << "Parent has been destroyed" << endl;
    }
}

2. 循環(huán)引用的檢測工具

Valgrind、AddressSanitizer 等工具可輔助檢測內(nèi)存泄漏。

靜態(tài)代碼分析器(如 Clang-Tidy)可識(shí)別潛在循環(huán)引用。

五、總結(jié)

場景特征

推薦策略

示例

明確單向所有權(quán)(如父子節(jié)點(diǎn))

所有者用

Parent-Child 模型

雙向依賴但需單向控制

主方向用

雙向鏈表

多對象共享資源

頂層管理用

緩存系統(tǒng)

無明確所有權(quán)

重新設(shè)計(jì)或雙向

聊天室和用戶

核心準(zhǔn)則:通過分析對象生命周期控制權(quán),確定shared_ptr和weak_ptr的使用。始終確保至少有一條所有權(quán)路徑不形成閉環(huán)。

  • 誰管理生命周期,誰用 shared_ptr。
  • 誰僅需引用對方,誰用 weak_ptr。
責(zé)任編輯:趙寧寧 來源: CppPlayer
相關(guān)推薦

2025-05-28 08:50:00

C++循環(huán)引用節(jié)點(diǎn)

2025-04-29 08:35:00

2025-06-24 10:00:00

智能指針代碼unique_ptr

2025-06-09 07:55:00

C++引用語言

2025-02-26 01:23:02

C++11Raw代碼

2010-01-15 18:06:20

C++引用

2024-12-04 09:47:26

C++頭文件實(shí)現(xiàn)類

2024-12-10 13:00:00

C++引用

2021-10-27 11:00:30

C++語言面試

2011-03-30 17:20:18

C++引用

2024-01-18 10:27:30

C++引用函數(shù)

2025-05-20 10:00:00

C++命名空間別名代碼

2025-05-23 08:15:00

C++constexpr字面類型

2011-07-20 15:58:53

C++引用

2010-02-02 10:33:22

C++引用

2024-01-29 16:55:38

C++引用開發(fā)

2019-06-25 10:46:04

Flutter開發(fā)APP

2025-05-26 03:20:00

2024-04-28 09:26:40

RustRTTI二進(jìn)制

2010-02-05 17:49:24

C++常量引用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)