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

C++四個智能指針的使用小結(jié)

 更新時間:2026年03月27日 10:06:57   作者:Ralph_Y  
智能指針的核心價值是自動管理內(nèi)存,解決裸指針的內(nèi)存泄漏、野指針等問題,本文就來詳細(xì)的介紹一下C++四個智能指針的使用,包括auto_ptr(廢棄)、unique_ptr(獨占所有權(quán))、shared_ptr(共享所有權(quán))、weak_ptr(弱引用),感興趣的可以了解一下

一、先搞懂:為什么需要智能指針?

C++ 原生指針(裸指針)最大的問題是手動管理內(nèi)存容易出錯,比如:

  • 忘記釋放內(nèi)存 → 內(nèi)存泄漏;
  • 提前釋放內(nèi)存 → 野指針(訪問已釋放的內(nèi)存);
  • 重復(fù)釋放內(nèi)存 → 程序崩潰;
  • 異常場景下(比如函數(shù)中途拋異常),釋放代碼執(zhí)行不到 → 內(nèi)存泄漏。

智能指針的核心是利用 RAII 機(jī)制(資源獲取即初始化):把內(nèi)存管理綁定到智能指針的生命周期,當(dāng)智能指針超出作用域(如函數(shù)結(jié)束、對象銷毀)時,自動調(diào)用析構(gòu)函數(shù)釋放內(nèi)存,徹底避免手動管理的問題。

二、C++ 四大智能指針詳解(附代碼示例)

C++ 標(biāo)準(zhǔn)庫(<memory> 頭文件)提供了 4 種智能指針,其中 auto_ptr 已被廢棄,重點掌握后 3 種:

智能指針核心特性適用場景線程安全
auto_ptr獨占所有權(quán),已廢棄無(C++11 后用 unique_ptr 替代)
unique_ptr獨占所有權(quán),不可拷貝單個對象/數(shù)組的獨占管理
shared_ptr共享所有權(quán),引用計數(shù)多個對象共享同一塊內(nèi)存引用計數(shù)線程安全,對象本身否
weak_ptr弱引用,不增加引用計數(shù)解決 shared_ptr 循環(huán)引用

1.auto_ptr(廢棄!僅作了解)

  • 問題:拷貝時會轉(zhuǎn)移所有權(quán)(原指針變?yōu)榭眨瑯O易導(dǎo)致野指針,C++11 已被 unique_ptr 取代。
  • 反例(為什么廢棄):
    #include <memory>
    #include <iostream>
    using namespace std;
    int main() {
        auto_ptr<int> p1(new int(10));
        auto_ptr<int> p2 = p1; // 拷貝后,p1 所有權(quán)轉(zhuǎn)移給 p2,p1 變?yōu)榭?
        cout << *p2 << endl;   // 正常輸出 10
        // cout << *p1 << endl; // 崩潰!p1 是空指針
        return 0;
    }

2.unique_ptr(最常用!獨占式智能指針)

  • 核心:保證同一時間只有一個 unique_ptr 指向一塊內(nèi)存,不可拷貝,僅可移動std::move)。
  • 優(yōu)勢:輕量級(性能接近裸指針),支持管理數(shù)組(unique_ptr<int[]>)。
  • 示例:
    #include <memory>
    #include <iostream>
    using namespace std;
    int main() {
        // 1. 基本使用:獨占內(nèi)存,超出作用域自動釋放
        unique_ptr<int> p(new int(10)); 
        cout << *p << endl; // 輸出 10
        // 2. 不可拷貝(編譯報錯)
        // unique_ptr<int> p2 = p; 
        // 3. 可移動(轉(zhuǎn)移所有權(quán))
        unique_ptr<int> p3 = move(p); 
        // cout << *p << endl; // 崩潰!p 已無所有權(quán)
        cout << *p3 << endl; // 輸出 10
        // 4. 管理數(shù)組(自動調(diào)用 delete[])
        unique_ptr<int[]> arr(new int[3]{1,2,3});
        cout << arr[1] << endl; // 輸出 2
        return 0; // p3、arr 超出作用域,自動釋放內(nèi)存
    }

3.shared_ptr(共享式智能指針)

  • 核心:通過引用計數(shù)管理內(nèi)存:每多一個 shared_ptr 指向同一塊內(nèi)存,計數(shù)+1;指針銷毀時計數(shù)-1;計數(shù)為 0 時,自動釋放內(nèi)存。
  • 注意:不能用裸指針初始化多個 shared_ptr(會導(dǎo)致重復(fù)釋放),推薦用 make_shared 初始化(更高效)。
  • 示例:
    #include <memory>
    #include <iostream>
    using namespace std;
    int main() {
        // 1. 初始化(推薦 make_shared,避免內(nèi)存碎片)
        shared_ptr<int> p1 = make_shared<int>(10);
        cout << p1.use_count() << endl; // 輸出 1(引用計數(shù))
        // 2. 拷貝:引用計數(shù)+1
        shared_ptr<int> p2 = p1;
        cout << p1.use_count() << endl; // 輸出 2
        cout << *p2 << endl;            // 輸出 10
        // 3. 銷毀一個指針:引用計數(shù)-1
        p1.reset(); // 手動釋放 p1 的所有權(quán)
        cout << p2.use_count() << endl; // 輸出 1
        return 0; // p2 超出作用域,計數(shù)變?yōu)?0,內(nèi)存釋放
    }

4.weak_ptr(弱引用指針,解決循環(huán)引用)

核心:指向 shared_ptr 管理的內(nèi)存,但不增加引用計數(shù),不會阻止內(nèi)存釋放;需先轉(zhuǎn)為 shared_ptr 才能訪問對象。

解決的問題shared_ptr 循環(huán)引用(如 A 指向 B,B 指向 A)會導(dǎo)致引用計數(shù)永遠(yuǎn)不為 0,內(nèi)存泄漏,weak_ptr 可破解。

示例(循環(huán)引用問題 + 解決):

#include <memory>
using namespace std;
// 循環(huán)引用問題(內(nèi)存泄漏)
struct A { shared_ptr<B> b; ~A() { cout << "A 析構(gòu)" << endl; } };
struct B { shared_ptr<A> a; ~B() { cout << "B 析構(gòu)" << endl; } };
// 用 weak_ptr 解決循環(huán)引用
struct C { shared_ptr<D> d; ~C() { cout << "C 析構(gòu)" << endl; } };
struct D { weak_ptr<C> c; ~D() { cout << "D 析構(gòu)" << endl; } };
int main() {
    // 1. 循環(huán)引用:析構(gòu)函數(shù)不會執(zhí)行,內(nèi)存泄漏
    auto a = make_shared<A>();
    auto b = make_shared<B>();
    a->b = b;
    b->a = a;
    // 2. 用 weak_ptr 解決:析構(gòu)函數(shù)正常執(zhí)行
    auto c = make_shared<C>();
    auto d = make_shared<D>();
    c->d = d;
    d->c = c; // D 用 weak_ptr 指向 C,不增加引用計數(shù)
    return 0;
}

輸出:

D 析構(gòu)
C 析構(gòu)

(A、B 的析構(gòu)函數(shù)未執(zhí)行,C、D 正常執(zhí)行)

三、智能指針的核心使用原則

  1. 優(yōu)先用 unique_ptr:性能最好,獨占所有權(quán),滿足大部分場景;
  2. 需要共享時用 shared_ptr:避免循環(huán)引用,搭配 weak_ptr;
  3. 禁止用裸指針初始化多個 shared_ptr:會導(dǎo)致重復(fù)釋放;
  4. 不要用智能指針管理非堆內(nèi)存(如棧上的對象):析構(gòu)時會調(diào)用 delete,導(dǎo)致崩潰;
  5. 自定義刪除器:如果管理的資源不是 new 分配的(如 malloc、文件句柄),需自定義刪除器:
    // 示例:管理文件句柄(自定義刪除器關(guān)閉文件)
    shared_ptr<FILE> fp(fopen("test.txt", "r"), [](FILE* f) { fclose(f); });

總結(jié)

  1. 智能指針的核心價值是自動管理內(nèi)存,解決裸指針的內(nèi)存泄漏、野指針等問題;
  2. unique_ptr 是首選(獨占、高效),shared_ptr 用于共享場景,weak_ptr 解決循環(huán)引用;
  3. auto_ptr 已廢棄,切勿使用;
  4. 本質(zhì)是 RAII 機(jī)制:把內(nèi)存釋放邏輯封裝到析構(gòu)函數(shù),利用 C++ 自動調(diào)用析構(gòu)的特性,實現(xiàn)“不用手動釋放”。

智能指針是C++ RAII(資源獲取即初始化)機(jī)制的核心實現(xiàn),旨在解決手動管理指針導(dǎo)致的內(nèi)存泄漏、野指針、重復(fù)釋放等問題。以下先深度解析shared_ptr的實現(xiàn)原理(基于參考回答優(yōu)化),再講解unique_ptrweak_ptr的實現(xiàn)邏輯與核心差異。

一、shared_ptr 實現(xiàn)詳解(帶完整可運行代碼)

shared_ptr的核心是引用計數(shù):多個shared_ptr共享同一個底層指針,引用計數(shù)記錄當(dāng)前指針被引用的次數(shù),僅當(dāng)計數(shù)為0時,才真正釋放底層內(nèi)存。

1. 核心設(shè)計思路

核心成員作用
T* ptr指向底層資源的原始指針
int* use_count引用計數(shù)的指針(所有共享對象指向同一塊內(nèi)存,保證計數(shù)共享)
拷貝構(gòu)造/賦值重載增加引用計數(shù)
析構(gòu)函數(shù)減少引用計數(shù),計數(shù)為0時釋放資源+計數(shù)內(nèi)存

2. 完整實現(xiàn)(修復(fù)參考回答的bug,補(bǔ)充線程安全)

#include <iostream>
#include <mutex> // 引入互斥鎖保證線程安全
using namespace std;
template <typename T>
class SharedPtr {
private:
    T* ptr;                // 底層資源指針
    int* use_count;        // 引用計數(shù)(指針形式,保證所有對象共享)
    mutex* mtx;            // 互斥鎖(保證多線程下計數(shù)操作原子性)
    // 私有輔助函數(shù):釋放當(dāng)前資源
    void release() {
        lock_guard<mutex> lock(*mtx); // 加鎖保證線程安全
        if (--(*use_count) == 0) {    // 引用計數(shù)減1,若為0則釋放資源
            delete ptr;               // 釋放底層內(nèi)存
            delete use_count;         // 釋放計數(shù)內(nèi)存
            delete mtx;               // 釋放鎖內(nèi)存
            ptr = nullptr;
            use_count = nullptr;
            mtx = nullptr;
        }
    }
public:
    // 1. 構(gòu)造函數(shù):接收原始指針
    SharedPtr(T* p = nullptr) : ptr(p) {
        try {
            use_count = new int(1);   // 初始計數(shù)為1
            mtx = new mutex();        // 初始化鎖
        } catch (...) {               // 內(nèi)存分配失敗,釋放資源避免泄漏
            delete ptr;
            ptr = nullptr;
            throw; // 拋出異常,讓上層處理
        }
    }
    // 2. 拷貝構(gòu)造函數(shù):共享資源,計數(shù)+1
    SharedPtr(const SharedPtr<T>& other) {
        ptr = other.ptr;
        use_count = other.use_count;
        mtx = other.mtx;
        // 加鎖更新計數(shù)(多線程安全)
        lock_guard<mutex> lock(*mtx);
        ++(*use_count);
    }
    // 3. 賦值運算符重載:先釋放自己的資源,再共享對方的資源
    SharedPtr<T>& operator=(const SharedPtr<T>& other) {
        // 防止自賦值(p = p)
        if (this == &other) return *this;
        // 第一步:釋放當(dāng)前對象持有的資源
        release();
        // 第二步:共享新對象的資源,計數(shù)+1
        ptr = other.ptr;
        use_count = other.use_count;
        mtx = other.mtx;
        lock_guard<mutex> lock(*mtx);
        ++(*use_count);
        return *this;
    }
    // 4. 析構(gòu)函數(shù):計數(shù)-1,計數(shù)為0則釋放資源
    ~SharedPtr() {
        if (use_count != nullptr) { // 避免重復(fù)釋放
            release();
        }
    }
    // 5. 重載解引用運算符:模擬原始指針行為
    T& operator*() const {
        if (ptr == nullptr) {
            throw runtime_error("解引用空指針");
        }
        return *ptr;
    }
    // 6. 重載->運算符:模擬原始指針行為
    T* operator->() const {
        if (ptr == nullptr) {
            throw runtime_error("訪問空指針成員");
        }
        return ptr;
    }
    // 7. 獲取引用計數(shù)
    int get_count() const {
        lock_guard<mutex> lock(*mtx);
        return *use_count;
    }
    // 8. 獲取原始指針(謹(jǐn)慎使用)
    T* get() const {
        return ptr;
    }
    // 禁用移動構(gòu)造/賦值(簡化版,C++11后可實現(xiàn))
    SharedPtr(SharedPtr<T>&&) = delete;
    SharedPtr<T>& operator=(SharedPtr<T>&&) = delete;
};
// 測試代碼
int main() {
    SharedPtr<int> p1(new int(10));
    cout << "p1計數(shù):" << p1.get_count() << endl; // 輸出1
    cout << "*p1 = " << *p1 << endl;             // 輸出10
    SharedPtr<int> p2 = p1;
    cout << "p1計數(shù):" << p1.get_count() << endl; // 輸出2
    cout << "p2計數(shù):" << p2.get_count() << endl; // 輸出2
    *p2 = 20;
    cout << "*p1 = " << *p1 << endl;             // 輸出20(共享資源)
    SharedPtr<int> p3(new int(30));
    p2 = p3; // p2賦值給p3,p1計數(shù)變?yōu)?,p3計數(shù)變?yōu)?
    cout << "p1計數(shù):" << p1.get_count() << endl; // 輸出1
    cout << "p3計數(shù):" << p3.get_count() << endl; // 輸出2
    return 0;
}

3. 關(guān)鍵細(xì)節(jié)(修復(fù)參考回答的問題)

  1. 線程安全
    • 參考回答未處理多線程,實際shared_ptr的引用計數(shù)操作必須加鎖;
    • 每個shared_ptr對象共享同一個互斥鎖,保證計數(shù)增減的原子性。
  2. 賦值運算符重載
    • 參考回答的賦值邏輯錯誤(先加對方計數(shù),再減自己計數(shù)),正確邏輯是“先釋放自己的資源,再共享對方的資源”;
    • 必須處理自賦值(p = p),否則會導(dǎo)致計數(shù)錯誤。
  3. 異常安全
    • 構(gòu)造函數(shù)中若use_count分配失敗,需釋放ptr避免內(nèi)存泄漏;
    • 解引用/訪問成員時檢查空指針,避免野指針訪問。

4. shared_ptr 核心特性

  • 共享所有權(quán):多個shared_ptr可指向同一資源;
  • 自動釋放:最后一個指向資源的shared_ptr析構(gòu)時,釋放底層內(nèi)存;
  • 線程安全
    • 引用計數(shù)的增減是原子操作(多線程安全);
    • shared_ptr的讀寫操作(如p = q)需手動加鎖(非線程安全)。

二、unique_ptr 實現(xiàn)詳解

unique_ptr的核心是獨占所有權(quán):同一時間只有一個unique_ptr能指向某個資源,禁止拷貝,僅支持移動(C++11)。

1. 核心設(shè)計思路

核心特性實現(xiàn)方式
獨占所有權(quán)禁用拷貝構(gòu)造/賦值運算符
移動語義實現(xiàn)移動構(gòu)造/賦值,轉(zhuǎn)移資源所有權(quán)
自動釋放析構(gòu)函數(shù)直接釋放底層資源(無需計數(shù))

2. 完整實現(xiàn)

#include <iostream>
#include <utility> // 引入move
using namespace std;

template <typename T>
class UniquePtr {
private:
    T* ptr; // 獨占的底層資源指針

public:
    // 1. 構(gòu)造函數(shù):接收原始指針
    explicit UniquePtr(T* p = nullptr) : ptr(p) {}

    // 2. 禁用拷貝構(gòu)造(獨占所有權(quán),禁止拷貝)
    UniquePtr(const UniquePtr<T>&) = delete;

    // 3. 禁用賦值運算符
    UniquePtr<T>& operator=(const UniquePtr<T>&) = delete;

    // 4. 移動構(gòu)造函數(shù):轉(zhuǎn)移資源所有權(quán)
    UniquePtr(UniquePtr<T>&& other) noexcept {
        ptr = other.ptr;
        other.ptr = nullptr; // 源對象置空,避免重復(fù)釋放
    }

    // 5. 移動賦值運算符:轉(zhuǎn)移資源所有權(quán)
    UniquePtr<T>& operator=(UniquePtr<T>&& other) noexcept {
        if (this == &other) return *this;

        // 釋放當(dāng)前資源
        delete ptr;
        // 轉(zhuǎn)移所有權(quán)
        ptr = other.ptr;
        other.ptr = nullptr;

        return *this;
    }

    // 6. 析構(gòu)函數(shù):直接釋放資源(無計數(shù),獨占所以直接刪)
    ~UniquePtr() {
        delete ptr;
        ptr = nullptr;
    }

    // 7. 重載解引用運算符
    T& operator*() const {
        if (ptr == nullptr) throw runtime_error("解引用空指針");
        return *ptr;
    }

    // 8. 重載->運算符
    T* operator->() const {
        if (ptr == nullptr) throw runtime_error("訪問空指針成員");
        return ptr;
    }

    // 9. 釋放資源(手動放棄所有權(quán))
    T* release() {
        T* temp = ptr;
        ptr = nullptr;
        return temp;
    }

    // 10. 重置資源
    void reset(T* p = nullptr) {
        delete ptr;
        ptr = p;
    }

    // 11. 獲取原始指針
    T* get() const {
        return ptr;
    }
};

// 測試代碼
int main() {
    UniquePtr<int> p1(new int(10));
    cout << "*p1 = " << *p1 << endl; // 輸出10

    // UniquePtr<int> p2 = p1; // 編譯錯誤:禁用拷貝構(gòu)造
    UniquePtr<int> p2 = move(p1); // 移動構(gòu)造,p1置空
    // cout << *p1 << endl; // 崩潰:p1已空
    cout << "*p2 = " << *p2 << endl; // 輸出10

    p2.reset(new int(20)); // 重置資源
    cout << "*p2 = " << *p2 << endl; // 輸出20

    return 0;
}

3. unique_ptr 核心特性

  • 獨占性:禁止拷貝,僅能通過std::move轉(zhuǎn)移所有權(quán);
  • 輕量級:無引用計數(shù),內(nèi)存開銷僅等于原始指針;
  • 高效:析構(gòu)時直接釋放資源,無計數(shù)操作開銷;
  • 支持?jǐn)?shù)組unique_ptr<int[]> 會自動調(diào)用delete[]釋放數(shù)組。

三、weak_ptr 實現(xiàn)詳解

weak_ptr是為解決shared_ptr循環(huán)引用問題而生的“弱引用”指針:

  • 不擁有資源所有權(quán),僅能觀察shared_ptr管理的資源;
  • 不增加引用計數(shù),不會阻止資源釋放;
  • 需通過lock()轉(zhuǎn)換為shared_ptr后才能訪問資源。

1. 核心設(shè)計思路

核心成員作用
T* ptr指向底層資源的指針(僅觀察,不擁有)
int* use_count共享shared_ptr的引用計數(shù)(僅讀取,不修改)
int* weak_count弱引用計數(shù)(記錄weak_ptr的數(shù)量)
mutex* mtx共享互斥鎖

2. 完整實現(xiàn)(依賴shared_ptr)

#include <iostream>
#include <mutex>
using namespace std;
// 先聲明SharedPtr,供WeakPtr使用
template <typename T> class SharedPtr;
template <typename T>
class WeakPtr {
private:
    T* ptr;                // 底層資源指針(僅觀察)
    int* use_count;        // 共享_ptr的強(qiáng)引用計數(shù)
    int* weak_count;       // 弱引用計數(shù)
    mutex* mtx;            // 共享鎖
    // 私有輔助函數(shù):釋放弱引用
    void release_weak() {
        lock_guard<mutex> lock(*mtx);
        if (--(*weak_count) == 0) { // 弱引用計數(shù)為0時,釋放計數(shù)內(nèi)存
            delete use_count;
            delete weak_count;
            delete mtx;
            use_count = nullptr;
            weak_count = nullptr;
            mtx = nullptr;
        }
    }
public:
    // 1. 構(gòu)造函數(shù):默認(rèn)構(gòu)造
    WeakPtr() : ptr(nullptr), use_count(nullptr), weak_count(nullptr), mtx(nullptr) {}
    // 2. 從shared_ptr構(gòu)造
    WeakPtr(const SharedPtr<T>& sp) {
        ptr = sp.get();
        use_count = sp.use_count_ptr(); // 需要SharedPtr暴露use_count指針(友元)
        weak_count = sp.weak_count_ptr();
        mtx = sp.get_mutex();
        lock_guard<mutex> lock(*mtx);
        ++(*weak_count); // 弱引用計數(shù)+1
    }
    // 3. 拷貝構(gòu)造
    WeakPtr(const WeakPtr<T>& wp) {
        ptr = wp.ptr;
        use_count = wp.use_count;
        weak_count = wp.weak_count;
        mtx = wp.mtx;
        lock_guard<mutex> lock(*mtx);
        ++(*weak_count);
    }
    // 4. 賦值運算符
    WeakPtr<T>& operator=(const WeakPtr<T>& wp) {
        if (this == &wp) return *this;
        if (weak_count != nullptr) release_weak(); // 釋放當(dāng)前弱引用
        ptr = wp.ptr;
        use_count = wp.use_count;
        weak_count = wp.weak_count;
        mtx = wp.mtx;
        lock_guard<mutex> lock(*mtx);
        ++(*weak_count);
        return *this;
    }
    // 5. 析構(gòu)函數(shù):弱引用計數(shù)-1
    ~WeakPtr() {
        if (weak_count != nullptr) {
            release_weak();
        }
    }
    // 6. 核心方法:lock()轉(zhuǎn)換為shared_ptr
    SharedPtr<T> lock() const {
        lock_guard<mutex> lock(*mtx);
        if (*use_count > 0) { // 強(qiáng)引用計數(shù)>0,資源未釋放
            return SharedPtr<T>(ptr, use_count, weak_count, mtx); // 自定義SharedPtr構(gòu)造函數(shù)
        }
        return SharedPtr<T>(); // 資源已釋放,返回空shared_ptr
    }
    // 7. 檢查資源是否有效(未被釋放)
    bool expired() const {
        lock_guard<mutex> lock(*mtx);
        return *use_count == 0;
    }
    // 8. 獲取強(qiáng)引用計數(shù)
    int use_count() const {
        lock_guard<mutex> lock(*mtx);
        return *use_count;
    }
    // 禁用移動構(gòu)造/賦值(簡化版)
    WeakPtr(WeakPtr<T>&&) = delete;
    WeakPtr<T>& operator=(WeakPtr<T>&&) = delete;
    // 友元聲明:讓SharedPtr訪問WeakPtr的私有成員
    friend class SharedPtr<T>;
};
// 補(bǔ)充SharedPtr的擴(kuò)展(支持WeakPtr)
template <typename T>
class SharedPtr {
private:
    T* ptr;
    int* use_count;
    int* weak_count; // 新增弱引用計數(shù)
    mutex* mtx;
    void release() {
        lock_guard<mutex> lock(*mtx);
        if (--(*use_count) == 0) {
            delete ptr;
            ptr = nullptr;
        }
        // 弱引用計數(shù)處理移交給WeakPtr
    }
    // 供WeakPtr::lock()調(diào)用的私有構(gòu)造函數(shù)
    SharedPtr(T* p, int* uc, int* wc, mutex* m) : ptr(p), use_count(uc), weak_count(wc), mtx(m) {
        lock_guard<mutex> lock(*mtx);
        ++(*use_count);
    }
public:
    // 原有構(gòu)造函數(shù)擴(kuò)展弱引用計數(shù)
    SharedPtr(T* p = nullptr) : ptr(p) {
        try {
            use_count = new int(1);
            weak_count = new int(0); // 初始弱引用計數(shù)為0
            mtx = new mutex();
        } catch (...) {
            delete ptr;
            ptr = nullptr;
            throw;
        }
    }
    // 暴露給WeakPtr的接口
    int* use_count_ptr() const { return use_count; }
    int* weak_count_ptr() const { return weak_count; }
    mutex* get_mutex() const { return mtx; }
    // 其余方法(拷貝構(gòu)造、賦值、析構(gòu)等)需適配weak_count,此處省略...
    T* get() const { return ptr; }
};

3. weak_ptr 核心特性

  • 弱引用:不增加強(qiáng)引用計數(shù),僅觀察資源;
  • 解決循環(huán)引用:如鏈表節(jié)點互相持有shared_ptr會導(dǎo)致計數(shù)無法歸零,改用weak_ptr即可;
  • 安全訪問:通過lock()獲取shared_ptr后才能訪問資源,避免訪問已釋放的資源;
  • expired():檢查資源是否已被釋放,防止野指針。

四、三種智能指針核心對比

特性shared_ptrunique_ptrweak_ptr
所有權(quán)共享獨占無(僅觀察)
引用計數(shù)強(qiáng)引用計數(shù)(控制釋放)弱引用計數(shù)(僅記錄)
拷貝/移動支持拷貝,移動禁用拷貝,支持移動支持拷貝,禁用移動
內(nèi)存開銷2個指針(資源+計數(shù))+鎖1個指針(僅資源)2個指針(資源+計數(shù))+鎖
核心場景多對象共享資源單對象獨占資源解決shared_ptr循環(huán)引用
訪問方式直接解引用直接解引用先lock()轉(zhuǎn)為shared_ptr

五、總結(jié)(核心要點回顧)

  1. shared_ptr
    • 核心是引用計數(shù),多線程下需加鎖保證計數(shù)原子性;
    • 拷貝/賦值時增加計數(shù),析構(gòu)時減少計數(shù),計數(shù)為0釋放資源;
    • 缺點:有計數(shù)開銷,易產(chǎn)生循環(huán)引用(需weak_ptr解決)。
  2. unique_ptr
    • 獨占所有權(quán),禁用拷貝,僅支持移動;
    • 輕量級、高效,無計數(shù)開銷,優(yōu)先用于單所有權(quán)場景;
    • 支持?jǐn)?shù)組類型,自動適配delete/delete[]。
  3. weak_ptr
    • 弱引用,不影響資源釋放,專門解決shared_ptr循環(huán)引用;
    • 需通過lock()轉(zhuǎn)為shared_ptr才能訪問資源,保證訪問安全;
    • 核心方法:lock()(獲取shared_ptr)、expired()(檢查資源有效性)。

智能指針的實現(xiàn)核心是RAII:將資源生命周期綁定到智能指針對象的生命周期,對象析構(gòu)時自動釋放資源,從根本上避免內(nèi)存泄漏。實際開發(fā)中優(yōu)先使用標(biāo)準(zhǔn)庫的std::shared_ptr/std::unique_ptr,其實現(xiàn)更完善(支持自定義刪除器、數(shù)組、線程安全等)。

到此這篇關(guān)于C++四個智能指針的使用小結(jié)的文章就介紹到這了,更多相關(guān)C++ 智能指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中STL的常用算法總結(jié)

    C++中STL的常用算法總結(jié)

    這篇文章主要介紹了C++?STL中一些常見算法的使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • C語言實現(xiàn)簡單三子棋程序

    C語言實現(xiàn)簡單三子棋程序

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)簡單三子棋程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • C++編程中用put輸出單個字符和cin輸入流的用法

    C++編程中用put輸出單個字符和cin輸入流的用法

    這篇文章主要介紹了C++編程中用put輸出單個字符和cin輸入流的用法,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • C++實現(xiàn)連連看游戲核心代碼

    C++實現(xiàn)連連看游戲核心代碼

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)連連看游戲核心代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • OpenGL實現(xiàn)邊緣填充算法

    OpenGL實現(xiàn)邊緣填充算法

    這篇文章主要為大家詳細(xì)介紹了OpenGL實現(xiàn)邊緣填充算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • 一文帶你掌握C語言中的文件操作

    一文帶你掌握C語言中的文件操作

    文件通常是駐留在外部介質(zhì)(如磁盤等)上的,在使用時才調(diào)入內(nèi)存中來,本文主要來和大家介紹一下C語言中的文件操作,有需要的可以了解下
    2024-02-02
  • 華為面試題數(shù)字大小寫轉(zhuǎn)換

    華為面試題數(shù)字大小寫轉(zhuǎn)換

    一個四位數(shù),如1024,1004,打印出他們的中文形式,如果一千零二十四,一千零四,大家參考使用吧
    2013-12-12
  • 詳解C++中的inline用法

    詳解C++中的inline用法

    在c/c++中,為了解決一些頻繁調(diào)用的小函數(shù)大量消耗??臻g(棧內(nèi)存)的問題,特別的引入了inline修飾符,表示為內(nèi)聯(lián)函數(shù)。 ??臻g就是指放置程序的局部數(shù)據(jù)(也就是函數(shù)內(nèi)數(shù)據(jù))的內(nèi)存空間
    2017-09-09
  • c語言strftime時間格式化示例

    c語言strftime時間格式化示例

    C/C++程序中需要程序顯示當(dāng)前時間,可以使用標(biāo)準(zhǔn)函數(shù)strftime,本文提供一個示例供大家參考
    2014-02-02
  • C++實現(xiàn)掃雷經(jīng)典小游戲

    C++實現(xiàn)掃雷經(jīng)典小游戲

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)掃雷經(jīng)典小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03

最新評論

久治县| 儋州市| 日喀则市| 孟州市| 龙泉市| 潮安县| 夏津县| 平果县| 阳谷县| 克拉玛依市| 丰县| 周口市| 东光县| 福泉市| 盐城市| 正定县| 儋州市| 拉萨市| 新沂市| 芜湖市| 武川县| 涡阳县| 昌图县| 望都县| 岑溪市| 泽库县| 赫章县| 白山市| 邯郸市| 乌鲁木齐市| 葫芦岛市| 天祝| 佛坪县| 重庆市| 锦州市| 石柱| 福贡县| 天长市| 科尔| 始兴县| 伊宁市|