自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

三分鐘掌握C++內(nèi)存管理精髓 :這三個指針絕對讓你相見恨晚!

開發(fā)
是不是經(jīng)常被指針搞得焦頭爛額?那些煩人的內(nèi)存泄漏和懸空指針讓你夜不能寐?別擔(dān)心,今天我要介紹一個超級英雄 - unique_ptr!它會讓你的指針煩惱一掃而空!

嘿,親愛的開發(fā)者們!還在為那些煩人的內(nèi)存泄漏而頭疼嗎? ?? 還在深夜被野指針搞得睡不著覺嗎? ?? 是不是覺得指針管理就像是在玩俄羅斯輪盤賭? ??

別擔(dān)心!今天我要介紹三位超級英雄,他們將徹底改變你寫代碼的方式! ??♂?

讓我們認識一下這三位神奇的角色:

  • unique_ptr: 獨來獨往的孤膽英雄 ??
  • shared_ptr: 團結(jié)友愛的好管家 ????????
  • weak_ptr: 神出鬼沒的觀察者 ??

準備好了嗎?讓我們開始這段奇妙的智能指針之旅吧! ?

提示:閱讀本文后,你會發(fā)現(xiàn)原來指針管理也可以這么簡單! ??

一、智能指針三劍客之 unique_ptr - 讓資源管理不再頭疼!

哎呀!你是不是經(jīng)常被指針搞得焦頭爛額??? 那些煩人的內(nèi)存泄漏和懸空指針讓你夜不能寐?別擔(dān)心,今天我要介紹一個超級英雄 - unique_ptr!它會讓你的指針煩惱一掃而空! ??♂?

1.為什么它這么厲害? 

想象一下,如果有一個既安全又高效的指針,用起來就像普通指針一樣簡單,是不是很棒?沒錯,unique_ptr 就是這樣一個神奇的存在!它就像是給你的指針加上了一層防護罩,再也不用擔(dān)心內(nèi)存泄漏啦! ???

2.傳統(tǒng)寫法 vs 現(xiàn)代寫法 - 一場驚心動魄的對決! 

讓我們先來看看傳統(tǒng)寫法是如何玩火的... 準備好了嗎? ??


Investment* makeInvestment() {
    Investment* p = new Stock("GOOGL", 50);  
    // 危險!這里要是拋個異常...
    // 這塊可憐的內(nèi)存就要變成孤魂野鬼啦! ??
    return p;  // 默默祈禱調(diào)用者還記得delete... ??
}

void investMoney() {
    Investment* p = makeInvestment();
    // ... 中間代碼 ...
    if(market_crash) {
        return; // 完蛋!忘記delete了! ??
    }
    delete p;  // 手抖地敲下delete,生怕重復(fù)刪除... ??
}

但是等等!現(xiàn)代C++給我們帶來了救星! ? 讓我們看看超級英雄 unique_ptr 是如何化腐朽為神奇的:

// 現(xiàn)代寫法 - 優(yōu)雅得讓人想哭! ??
unique_ptr<Investment> makeInvestment() {
    return make_unique<Stock>("GOOGL", 50);  // 異常安全?早就搞定了! ??
}

void investMoney() {
    auto investment = makeInvestment(); 
    // ... 中間代碼 ...
    if(market_crash) {
        return; // 放心回家吧,unique_ptr會處理好一切! ??
    }
} // 揮一揮衣袖,不帶走一片內(nèi)存~ ??

// 還想更酷一點?來看看這個! ??
void investMoneyWithCustomDeleter() {
    auto deleter = [](Investment* p) {
        cout << "優(yōu)雅地清理投資..." << endl;
        delete p;
    };
    
    unique_ptr<Investment, decltype(deleter)> 
        investment(new Stock("TSLA", 200), deleter);
    // ... 
} // 就是這么專業(yè)! ??

看到差別了嗎?這就是傳說中的"代碼自由"! 讓我們永遠告別手動內(nèi)存管理的噩夢吧! ??

3.unique_ptr 解決了哪些問題? - 超級英雄的四大神技! 

(1) 內(nèi)存泄漏? 哈!那是什么東西? ??

  • 析構(gòu)函數(shù)自動出擊,片甲不留! ??
  • 就算異常來搗亂,也能全身而退! ???

(2) 重復(fù)釋放? 做夢去吧! ??

  • 獨占所有權(quán),一山不容二虎! ??
  • 轉(zhuǎn)移時自動置空,永不走空! ?

(3) 忘記釋放? 這事兒交給我! ??

  • 作用域結(jié)束自動清理,就像家務(wù)小能手! ??
  • delete?那是什么古老的咒語? ??

(4) 所有權(quán)不明確? 我的地盤我做主! ??

  • 移動語義明明白白,清清楚楚! ??
  • 編譯器都幫你盯著,有問題立馬報警! ??

二、智能指針三劍客之 shared_ptr - 讓資源共享不再是噩夢!

還在為多個對象共享同一個資源而煩惱嗎??? 資源釋放的時機讓你頭疼不已??? 別擔(dān)心,今天我要介紹的這位超級英雄 - shared_ptr 能幫你輕松解決這些問題! ??♂?

1.為什么你需要這位英雄?

想象這個場景:你有一張超高清壁紙,好幾個窗口都想用它做背景。如果每個窗口都復(fù)制一份,那內(nèi)存豈不是要爆炸???

但是如果用我們的英雄 shared_ptr,問題就迎刃而解了!它就像一個帶計數(shù)器的管家,幫所有人管理這份共享的資源。等到最后一個使用者說"不用了",管家才會把資源收起來。優(yōu)雅不優(yōu)雅???

2.看看不用智能指針的恐怖故事

// 傳統(tǒng)寫法 - 這簡直就是一個噩夢般的故事... ??
class Widget {
    BigImage* image;  // 一個危險的野指針,像定時炸彈! ??
public:
    Widget(BigImage* img) : image(img) {}
    ~Widget() { 
        // delete image; // 刪還是不刪?這是一個世紀難題! ??
        // 刪了會不會導(dǎo)致程序爆炸?不刪會不會變成幽靈在內(nèi)存里游蕩?
    }
};

void scaryExample() {
    // 故事開始于一個深夜... ??
    BigImage* img = new BigImage("huge.jpg");  // 召喚出一個神秘的指針

    Widget w1(img);  // 第一個對象說:"這是我的!"
    Widget w2(img);  // 第二個對象說:"不,這也是我的!"
    
    // 現(xiàn)在的情況變得很微妙... ??
    // - 誰才是真正的主人?
    // - 誰該負責(zé)清理?
    // - 如果都刪除會發(fā)生什么?
    // - 如果都不刪除又會怎樣?
    
    // 程序員開始失眠了... ??
    // 這段代碼就像一個定時炸彈,隨時可能爆炸!
    // 讓我們快點看看智能指針是如何拯救世界的! ??
}

想知道如何化解這個危機嗎?且聽下回分解,看看 shared_ptr 如何華麗登場! ?

3.見證奇跡的時刻 - shared_ptr 閃亮登場! 

class Widget {
    shared_ptr<BigImage> image;  // 請看!超級管家駕到! ??
public:
    Widget(shared_ptr<BigImage> img) : image(img) {}
    // 析構(gòu)函數(shù)?哈!讓管家來操心這些瑣事吧! ??
};

void amazingExample() {
    // ?? 第一幕:創(chuàng)建共享資源
    auto img = make_shared<BigImage>("huge.jpg");  // 管家:新資源已就位!
    
    // ?? 第二幕:資源共享的魔法時刻
    Widget w1(img);  // 管家掏出小本本:?? "好的,第一位使用者登記完畢!"
    Widget w2(img);  // 管家繼續(xù)記錄:?? "第二位來了,已經(jīng)有兩位了呢~"
    
    // ?? 第三幕:完美謝幕
    // 不用操心善后工作
    // 當(dāng)最后一位演員退場時
    // 管家會優(yōu)雅地清理一切
    // 就像變魔術(shù)一樣! ???
} // 管家微笑著:一切盡在掌控之中! ??

想知道這位神通廣大的管家還有什么驚人絕技嗎?且聽下回分解! ??

4. unique_ptr vs shared_ptr - 誰才是你的真命天子? 

讓我們來看看這兩位C++世界的頂級高手之間的終極對決! ??

雖然 unique_ptr 是個獨來獨往的俠客,但有時候我們需要一個更會"社交"的伙伴。這時候,就輪到我們的 shared_ptr 大顯身手啦! ?

(1) 資源共享場景 - 獨行俠遇到的困境 ??

// unique_ptr: "對不起,我不會分身術(shù)..." ??
unique_ptr<Config> config = loadConfig();
// worker1: "我要配置!"
// worker2: "我也要!"
// unique_ptr: "但我只能跟一個人走..." 
// 場面一度很尷尬... ??

// shared_ptr: "讓我來解決這個問題!" ??♂?
shared_ptr<Config> config = make_shared<Config>();
worker1->setConfig(config);  // "給你一份!"
worker2->setConfig(config);  // "你也有!"
// 所有人開開心心地共享資源,皆大歡喜! ??

(2) 生命周期管理 - 是時候展現(xiàn)真正的技術(shù)了! ??

  • unique_ptr: "我要準確知道什么時候說再見" ??
  • shared_ptr: "放心交給我,我會照顧好一切" ??
  • 異步任務(wù)和回調(diào)函數(shù): "終于等到你!" ??

(3) 緩存系統(tǒng) - 共享才是王道 ??

class Cache {
    // shared_ptr: "讓我來當(dāng)這個資源管家!" 
    unordered_map<string, shared_ptr<Resource>> resources;
public:
    shared_ptr<Resource> get(const string& key) {
    // "不管多少人來要資源,我都能應(yīng)付自如~" ??
    // "用完自動收拾,完全不用操心!" ?
    return resources[key];
    }
};

記住: unique_ptr 是獨行俠, shared_ptr 是社交達人,要根據(jù)場景選擇合適的英雄! ??

提示: 雖然 shared_ptr 很強大,但也別忘了它的社交能力是要付出代價的(性能開銷)哦! ??

5. shared_ptr 的超能力

(1) 自動計數(shù)功能

  • 新人用資源時 +1
  • 不用了就 -1
  • 沒人用了就自動清理
  • 就像一個盡職盡責(zé)的管家! ??

(2) 線程安全防護

  • 計數(shù)器的加減都是原子操作
  • 多線程環(huán)境也完全不怕
  • 簡直就是多線程克星! ???

(3) 還能自定義清理方式

shared_ptr<File> fp(fopen("test.txt", "r"), 
    [](FILE* f){ fclose(f); });  // 優(yōu)雅~

記住:共享不是免費的,shared_ptr 比 unique_ptr 有更多開銷。所以要根據(jù)實際需求選擇合適的智能指針! ??

三、智能指針三劍客之 weak_ptr - 打破循環(huán)引用的救星!

還在為 shared_ptr 循環(huán)引用導(dǎo)致的內(nèi)存泄漏而煩惱嗎? ?? weak_ptr 來救場啦! 它就像是 shared_ptr 的好朋友,可以觀察但不會干擾計數(shù),完美解決循環(huán)引用問題! ??♂?

1.為什么需要它?

想象這個場景:你有兩個類互相引用對方。如果都用 shared_ptr,那引用計數(shù)永遠不會變成0,資源永遠不會釋放! 這就是著名的"循環(huán)引用"問題。??

但是用了 weak_ptr,它就像一個"旁觀者",可以看到對象是否還活著,但不會影響它的生命周期。完美! ??

2.看看不用它有多可怕

想象一下,這段代碼就像是在講述兩個好朋友 Lucy 和 Lily 的故事:

// 糟糕的設(shè)計 - 內(nèi)存永遠不會釋放! 
class Person {
    string name;
    shared_ptr<Person> best_friend;  // 相互引用
public:
    Person(const string& n) : name(n) {}
    void makeFriend(shared_ptr<Person> friend_) {
        best_friend = friend_;
    }
};

void createFriends() {
    auto lucy = make_shared<Person>("Lucy");
    auto lily = make_shared<Person>("Lily");
    
    lucy->makeFriend(lily);  // Lucy的引用計數(shù)變成2
    lily->makeFriend(lucy);  // Lily的引用計數(shù)變成2
    
    // 函數(shù)結(jié)束時,兩個對象都還有一個引用
    // 所以永遠不會被刪除!
} // 內(nèi)存泄漏! ??

為什么這是個問題?

(1) 死循環(huán)的友誼

  • Lucy說:"我要永遠抓住Lily!" (引用計數(shù)+1)
  • Lily說:"我也要永遠抓住Lucy!" (引用計數(shù)+1)
  • 結(jié)果: 兩個人都放不開對方,永遠被困在內(nèi)存里! ??

(2) 內(nèi)存泄漏的后果

  • 系統(tǒng): "該清理了!"
  • Lucy: "不行!我還抓著Lily呢!"
  • Lily: "我也抓著Lucy呢!"
  • 系統(tǒng): "好吧..." (無奈臉) ????

這就像兩個人互相拉著對方的手,都不愿意先放開。結(jié)果就是兩個人都走不了,永遠站在那里! ??♀???♀?

這就是為什么我們需要 weak_ptr - 它就像是一個"松散的握手",可以隨時放開,不會造成這種尷尬的永恒循環(huán)!

3. weak_ptr 英雄登場!

讓我們看看如何用 weak_ptr 來優(yōu)雅地解決循環(huán)引用問題。在這個例子中,我們將創(chuàng)建兩個可以互相成為好朋友的 Person 對象,但這次我們使用 weak_ptr 來存儲朋友關(guān)系,這樣就不會造成循環(huán)引用了! ??

class Person {
    string name;
    weak_ptr<Person> best_friend;  // 改用weak_ptr
public:
    Person(const string& n) : name(n) {}
    void makeFriend(shared_ptr<Person> friend_) {
        best_friend = friend_;  // 不會增加引用計數(shù)
    }
    
    void meetFriend() {
        // 需要時嘗試提升為shared_ptr
        if (auto friend_ptr = best_friend.lock()) {
            cout << "見到好朋友: " << friend_ptr->name << endl;
        } else {
            cout << "朋友已不在..." << endl;
        }
    }
};

void createFriends() {
    auto lucy = make_shared<Person>("Lucy");
    auto lily = make_shared<Person>("Lily");
    
    lucy->makeFriend(lily);  // 不會增加引用計數(shù)
    lily->makeFriend(lucy);  // 不會增加引用計數(shù)
    
} // 完美釋放! ?

看到了嗎?通過使用 weak_ptr,我們不僅解決了循環(huán)引用的問題,還增加了一個 meetFriend() 方法來安全地檢查朋友是否還存在。當(dāng)需要訪問好朋友時,我們使用 lock() 方法來獲取一個臨時的 shared_ptr,這樣就能安全地訪問對象了。如果對象已經(jīng)被釋放,lock() 會返回一個空指針,讓我們能夠優(yōu)雅地處理這種情況。這就是 weak_ptr 的魔力! ?

4. weak_ptr 的超能力

(1) 觀察但不占有

  • 不會增加引用計數(shù)
  • 可以安全地觀察對象是否存在
  • 完美解決循環(huán)引用問題

(2) 安全檢查機制

  • 使用前需要先檢查對象是否還活著
  • 通過 lock() 獲取 shared_ptr
  • 避免訪問已釋放的對象

(3) 常見使用場景

class EventManager {
    weak_ptr<Widget> widget;  // 不影響Widget的生命周期
public:
    void setWidget(shared_ptr<Widget> w) {
        widget = w;
    }
       
    void notify() {
        if (auto w = widget.lock()) {
            w->onEvent();  // 安全調(diào)用
        }
    }
};

(4) 使用建議

  • 用于打破循環(huán)引用
  • 觀察者模式中使用
  • 緩存系統(tǒng)中使用
  • 需要對象存在性檢查的場景

記住:weak_ptr 是觀察者而非所有者,它讓你的代碼更加安全可靠! 

四、智能指針三劍客總結(jié)

(1) unique_ptr - 獨行俠 ??

  1. 性格: "我是獨行俠,不跟任何人共享資源!"
  2. 特長: 自動清理、零開銷、移動轉(zhuǎn)移
  3. 口頭禪: "這是我的地盤,我說了算!" ??

(2) shared_ptr - 社交達人 ????????

  • 性格: "來來來,大家一起用,有我在不用擔(dān)心!"
  • 特長: 引用計數(shù)、自動清理、多人共享
  • 口頭禪: "我的資源就是你的資源~" ??

(3) weak_ptr - 神秘觀察者 ??

  • 性格: "我就看看,不參與,不計數(shù)~"
  • 特長: 打破循環(huán)引用、安全觀察、不影響生命周期
  • 口頭禪: "我只是個觀察者,隨時可以放手" ??

他們的口號是:

"再見了,內(nèi)存泄漏!永別了,野指針!C++的世界,有我們守護!" ?

使用建議:

  • 默認選擇: unique_ptr (除非你真的需要共享)
  • 需要共享: shared_ptr (記住要付出性能代價哦)
  • 循環(huán)引用: weak_ptr 來救場!

記?。哼x擇合適的智能指針,就像選擇超級英雄一樣重要!讓我們一起創(chuàng)造更安全、更優(yōu)雅的代碼世界吧!??

責(zé)任編輯:趙寧寧 來源: everystep
相關(guān)推薦

2021-12-17 07:47:37

IT風(fēng)險框架

2022-03-26 09:06:40

ActorCSP模型

2020-05-06 09:18:56

Pandas函數(shù)大數(shù)據(jù)技術(shù)

2025-02-13 08:04:49

spliceCPU數(shù)據(jù)

2024-05-16 11:13:16

Helm工具release

2024-12-11 12:00:00

C++拷貝

2018-02-07 14:54:17

Riverbed應(yīng)用性能管理數(shù)字體驗

2009-11-09 12:55:43

WCF事務(wù)

2024-12-18 10:24:59

代理技術(shù)JDK動態(tài)代理

2021-04-14 09:22:18

Python技巧交換變量值

2024-01-29 00:51:39

前端開發(fā)利器

2022-02-17 09:24:11

TypeScript編程語言javaScrip

2021-04-20 13:59:37

云計算

2023-12-27 08:15:47

Java虛擬線程

2024-01-16 07:46:14

FutureTask接口用法

2024-08-30 08:50:00

2015-10-27 10:12:21

r語言命令相見恨晚

2013-06-28 14:30:26

棱鏡計劃棱鏡棱鏡監(jiān)控項目

2020-06-30 10:45:28

Web開發(fā)工具

2025-02-24 10:40:55

點贊
收藏

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