C++11中智能指針的使用(shared_ptr、unique_ptr、weak_ptr)

C++11中智能指針的使用(shared_ptr、unique_ptr、weak_ptr)

一、shared_ptr原理

shared_ptr 是另一種智能指針,用于實現多個 shared_ptr 實例共享同一個對象的所有權。它通過內部的控制塊(通常是一個包含計數器和指向對象的指針的結構)來管理對象的生命周期。每當一個新的 shared_ptr 被創建并指向對象時,控制塊中的計數器就會遞增;每當一個 shared_ptr 被銷毀或重置時,計數器就會遞減。當計數器減至零時,對象被刪除。

1.std::shared_ptr的原理

std::shared_ptr 的核心原理是引用計數。它通過一個**控制塊(Control Block)**來管理對象的生命周期。控制塊記錄了以下信息:

1.1 引用計數(Strong Count)

表示當前有多少個 std::shared_ptr 正在管理同一個對象。

當一個 std::shared_ptr 被復制時,引用計數加1。

當一個 std::shared_ptr 被銷毀時,引用計數減1。

當引用計數變為0時,對象會被自動釋放。

1.2 弱引用計數(Weak Count)

用于支持 std::weak_ptr,表示有多少個 std::weak_ptr 正在觀察這個對象。

當弱引用計數變為0時,控制塊本身也會被銷毀。

1.3 刪除器(Deleter)

一個函數對象,用于在對象被銷毀時執行清理操作(如釋放內存)。

1.4 分配器(Allocator)

用于分配和釋放內存。

1.1 控制塊的結構

控制塊通常是一個獨立的結構體,與 std::shared_ptrstd::weak_ptr 共享。它的結構大致如下:

struct ControlBlock {int* ptr;          // 指向被管理的對象unsigned* strong;  // 引用計數(Strong Count)unsigned* weak;    // 弱引用計數(Weak Count)Deleter deleter;   // 刪除器
};
1.2 生命周期管理
  • 當創建一個新的 std::shared_ptr 時,控制塊會被初始化,引用計數設置為1。

  • 當一個 std::shared_ptr 被復制時,引用計數加1。

  • 當一個 std::shared_ptr 被銷毀時,引用計數減1。如果引用計數變為0,控制塊會調用刪除器來釋放對象。

  • 當最后一個 std::weak_ptr 被銷毀時,控制塊本身也會被銷毀。

1.3 引用計數的線程安全性

std::shared_ptr 的引用計數操作是線程安全的。它使用原子操作來保證在多線程環境下引用計數的正確性。

2、std::shared_ptr的用法

2.1 創建 std::shared_ptr
(1)使用 std::make_shared

推薦使用 std::make_shared 來創建 std::shared_ptr,因為它更高效且安全。

#include <iostream>
#include<memory>
using namespace std;int main()
{// 創建一個shared_ptrshared_ptr<int> ptr = make_shared<int>(20);cout << "Value = "<< *ptr << endl;
}

std::make_shared 會同時分配對象和控制塊的內存,減少了內存分配的次數。

(2)直接構造

也可以通過構造函數直接創建,但需要小心避免懸掛指針。

 int* ptr2 = new int(10);shared_ptr<int> ptr3(ptr2);
(3)從其他智能指針轉換

std::shared_ptr 可以從 std::unique_ptr 或其他 std::shared_ptr 轉換而來。

std::shared_ptr<int> ptr3 = std::make_shared<int>(42);
std::shared_ptr<int> ptr4 = ptr3; // 復制構造,引用計數增加
2.2 引用計數機制

std::shared_ptr 的核心是引用計數。當一個 std::shared_ptr 被復制時,引用計數會增加;當一個 std::shared_ptr 被銷毀時,引用計數會減少。當引用計數為零時,它所管理的對象會被自動釋放。

std::shared_ptr<int> ptr5 = std::make_shared<int>(100);
{std::shared_ptr<int> ptr6 = ptr5; // 引用計數 +1std::cout << "Value: " << *ptr6 << std::endl;std::cout << "ptr5 Use_Count: " << ptr5.use_count() << std::endl;std::cout << "ptr6 Use_Count: " << ptr6.use_count() << std::endl;} // ptr6 超出作用域,引用計數 -1
std::cout << "Value: " << *ptr5 << std::endl; // 仍然可以訪問
std::cout << "Use_Count: " << ptr5.use_count() << std::endl;

代碼運行結果:
在這里插入圖片描述

在C++中通過 std::shared_ptr 的成員函數 use_count() 來獲取當前 shared_ptr 的引用計數。這個函數返回一個 std::size_t 類型的值,表示當前有多少個 std::shared_ptr 共享同一個控制塊。

2.3 使用自定義刪除器

如果需要對對象進行特殊處理(如釋放資源或調用特定函數),可以為 std::shared_ptr 提供自定義刪除器。

std::shared_ptr<int> ptr7(new int(30), [](int* p) {cout << "Custom Deleter Call" << endl;delete p;});

在這里插入圖片描述

程序結束,調用客戶自定義的刪除器。

2.4 使用 std::weak_ptr 避免循環引用

std::shared_ptr 可能會導致循環引用問題,從而無法正確釋放資源。通過 std::weak_ptr 可以解決這個問題。

class B;class A
{
public:shared_ptr<B> m_ptrB;~A() { cout << "A 析構" << endl; };
};class B
{
public:shared_ptr<A> m_ptrA;~B() { cout << "B 析構" << endl; };
};int main()
{shared_ptr<A> ptrA = make_shared<A>();shared_ptr<B> ptrB = make_shared<B>();ptrA->m_ptrB = ptrB;ptrB->m_ptrA = ptrA;
}

上述代碼運行時不會調用析構函數。

在這里插入圖片描述

解決辦法:將B類中的shared_ptr改為weak_ptr后,程序運行結果:

在這里插入圖片描述

2.5 其他操作
  • reset():釋放當前管理的對象,并可選地綁定到新的對象。

  • use_count():返回當前對象的引用計數。

  • get():返回底層裸指針(不推薦直接使用,僅在必要時)。

std::shared_ptr<int> ptr8 = std::make_shared<int>(200);
std::cout << "Use count: " << ptr8.use_count() << std::endl; // 輸出引用計數
ptr8.reset(); // 釋放對象

3、注意事項

  1. 循環引用問題

    • 如果兩個或多個 std::shared_ptr 相互引用,會導致引用計數永遠不會變為0,從而無法釋放對象。

    • 使用 std::weak_ptr 可以解決循環引用問題。

  2. 不要直接操作底層指針

    • 盡量避免使用 get() 獲取底層指針,因為這可能導致懸掛指針或內存泄漏。

    • 如果需要操作底層指針,建議使用 std::weak_ptr 來確保對象仍然有效。

  3. 性能開銷

    • std::shared_ptr 的引用計數操作是線程安全的,但會帶來一定的性能開銷。

    • 如果不需要線程安全,可以考慮使用 std::unique_ptr

  4. 優先使用 std::make_shared

    std::make_shared 會同時分配對象和控制塊的內存,減少了內存分配的次數,性能更好。

4、注意事項

std::shared_ptr 是一種非常強大的智能指針工具,適用于需要共享所有權的場景。它通過引用計數自動管理內存,減少了內存泄漏和懸掛指針的風險。但在使用時需要注意以下幾點:

  • 盡量避免循環引用,必要時使用 std::weak_ptr

  • 不要直接操作底層指針,除非絕對必要。

  • 優先使用 std::make_shared 創建 std::shared_ptr,因為它更高效。

二、unique_ptr原理

unique_ptr是獨占式的智能指針,每一次只會有一個指針指向其給定的對象。當unique_ptr離開其作用域時,其所指的對象會被自動刪除,并且該對象擁有的任何資源都會被釋放。

std::unique_ptr 是 C++11 引入的一種智能指針,用于管理動態分配的資源(如通過 new 分配的內存)。它的核心原理是通過獨占所有權語義來自動管理資源的生命周期,確保資源在合適的時機被釋放,從而避免內存泄漏和野指針問題。

以下是 std::unique_ptr 的工作原理和關鍵特性:

1. 獨占所有權

std::unique_ptr 采用獨占所有權機制,即同一時間只能有一個 unique_ptr 指向某個資源。這意味著:

  • 不能復制unique_ptr 不能被復制(即沒有拷貝構造函數和拷貝賦值運算符),因為復制會導致多個指針指向同一資源,從而破壞所有權的獨占性。

    微信截圖_20250315111348

  • 可以移動unique_ptr 支持移動語義(通過移動構造函數和移動賦值運算符),允許將資源的所有權從一個 unique_ptr 轉移到另一個 unique_ptr。移動操作會將原指針置為 nullptr,確保資源的唯一所有權。

    微信截圖_20250315111447

2. 自動釋放資源

std::unique_ptr 在以下情況下會自動釋放其管理的資源:

  • 析構函數:當 unique_ptr 被銷毀(如超出作用域、對象析構)時,它會調用資源的析構函數(如 delete)來釋放資源。

  • 重置:通過調用 reset() 方法,可以手動釋放當前資源,并可選擇分配新的資源。

    微信截圖_20250315111954

3. 定制刪除器

std::unique_ptr 允許用戶自定義刪除器(deleter),這使得它不僅可以管理動態分配的內存,還可以管理其他類型的資源(如文件句柄、網絡連接等)。刪除器是一個可調用對象,用于定義資源的釋放方式。默認情況下,unique_ptr 使用 delete 作為刪除器,但用戶可以通過模板參數或構造函數傳遞自定義刪除器。

struct FileDeleter
{void operator()(FILE* file){fclose(file);cout << "Custom Deleter called" << endl;}
};unique_ptr<FILE,FileDeleter> file(fopen("1.txt","r"));
file.reset(); // 調用自定義刪除器關閉文件

4. 實現原理

std::unique_ptr 的實現基于模板和智能指針的底層機制:

模板參數std::unique_ptr 是一個模板類,通常有兩個模板參數:

T:指針指向的類型。

Deleter:刪除器類型(默認為 std::default_delete<T>)。

內部存儲unique_ptr 內部存儲一個裸指針(T*)和一個刪除器對象。它通過操作這個裸指針來管理資源,并在需要時調用刪除器釋放資源。

移動語義unique_ptr 的移動構造函數和移動賦值運算符通過交換內部指針和刪除器來實現資源的轉移,確保所有權的唯一性。

5. 使用示例

以下是一個簡單的 std::unique_ptr 使用示例:

#include <iostream>
#include <memory>struct Foo // object to manage
{Foo() { std::cout << "Foo...\n"; }~Foo() { std::cout << "~Foo...\n"; }
};struct D // deleter
{void operator() (Foo* p){std::cout << "Calling delete for Foo object... \n";delete p;}
};int main()
{std::cout << "Creating new Foo...\n";std::unique_ptr<Foo, D> up(new Foo(), D()); // up owns the Foo pointer (deleter D)std::cout << "Replace owned Foo with a new Foo...\n";up.reset(new Foo());  // calls deleter for the old onestd::cout << "Release and delete the owned Foo...\n";up.reset(nullptr);      
}

代碼運行結果:

微信截圖_20250315122904

6. 優點

自動管理資源:避免手動調用 delete,減少內存泄漏風險。

獨占所有權:確保同一時間只有一個指針管理資源,避免野指針問題。

支持自定義刪除器:可以管理除動態內存之外的其他資源。

輕量級std::unique_ptr 通常只有裸指針大小,性能開銷極小。

7.缺點

  • 不能復制:由于獨占所有權,unique_ptr 不能被復制,這在某些場景下可能需要額外的邏輯來處理。
  • 依賴移動語義:需要 C++11 或更高版本支持,因為其依賴于移動構造函數和移動賦值運算符。

總之,std::unique_ptr 是一種非常強大且輕量級的智能指針,適用于大多數需要管理動態資源的場景。

三、weak_ptr原理

在C++中,weak_ptr是一種智能指針,用于解決shared_ptr的循環引用問題。它不擁有對象的所有權,而是觀察shared_ptr管理的對象,避免增加引用計數。以下是weak_ptr的原理和用法詳解:

1. weak_ptr的核心原理

不增加引用計數weak_ptr指向由shared_ptr管理的對象,但不會增加其引用計數。當最后一個shared_ptr被銷毀時,對象仍會被釋放,即使有weak_ptr存在。

觀察者模式weak_ptr只是"觀察"資源,不控制生命周期。若要訪問資源,需臨時轉換為shared_ptr(通過lock()方法)。

解決循環引用:在相互持有shared_ptr的場景中(如雙向鏈表、父-子對象),使用weak_ptr打破循環,防止內存泄漏.

1.1 std::shared_ptr 的關系
  • std::weak_ptr 是基于 std::shared_ptr 的。它不會增加對象的引用計數,但會與 std::shared_ptr 共享對象的控制塊(control block)。控制塊中包含了對象的引用計數和弱引用計數。

  • 引用計數(use_count):記錄有多少個 std::shared_ptr 指向對象。當引用計數為 0 時,對象會被銷毀。

  • 弱引用計數(weak_count):記錄有多少個 std::weak_ptr 指向對象。弱引用計數不會影響對象的生命周期,但當對象被銷毀時,所有指向該對象的 std::weak_ptr 會失效。

1.2 實現原理
  • 當創建一個 std::weak_ptr 時,它會從一個 std::shared_ptr 或另一個 std::weak_ptr 中獲取控制塊的指針,并增加弱引用計數。

  • 當使用 std::weak_ptrlock() 方法時,它會檢查控制塊中的對象是否仍然存在。如果對象存在,它會返回一個指向該對象的 std::shared_ptr,并增加引用計數;如果對象已經被銷毀,則返回一個空的 std::shared_ptr

  • 當一個 std::weak_ptr 被銷毀時,它會減少弱引用計數。當弱引用計數和引用計數都為 0 時,控制塊也會被銷毀。

2. 基本用法

2.1** 創建weak_ptr**

必須從shared_ptr或另一個weak_ptr構造.

std::shared_ptr 創建:從 std::shared_ptr 創建:

std::shared_ptr<int> ptr = std::make_shared<int>(10);
std::weak_ptr<int> w_ptr(ptr); // 從shared_ptr中構造

從另一個 std::weak_ptr 創建:

 std::weak_ptr<int> w_ptr2(w_ptr);
2.2** 檢查對象是否仍然存在**
  • 使用 expired() 方法檢查對象是否已經被銷毀:
 if (w_ptr2.expired()){std::cout << "Object has been destroyed." << std::endl; }else{std::cout << "Object still exists." << std::endl;}
2.3獲取對象的 std::shared_ptr
  • 使用 lock() 方法獲取對象的 std::shared_ptr
 std::shared_ptr<int> shared_from_weak = w_ptr2.lock();if (shared_from_weak) {std::cout << "Accessing object: " << *shared_from_weak << std::endl;}else {std::cout << "Object has been destroyed." << std::endl;}

如果對象仍然存在,lock() 方法會返回一個指向該對象的 std::shared_ptr;如果對象已經被銷毀,則返回一個空的 std::shared_ptr

3、std::weak_ptr 的使用場景

3.1解決循環引用問題
  • 在使用 std::shared_ptr 時,可能會出現循環引用的情況,導致對象無法被正確銷毀。例如,兩個對象互相持有對方的 std::shared_ptr,它們的引用計數永遠不會為 0。

  • 通過將其中一個引用改為 std::weak_ptr,可以打破循環引用。例如:

class B;class A {
public:std::shared_ptr<B> b_ptr;
};class B {
public:std::weak_ptr<A> a_ptr; // 使用 weak_ptr 避免循環引用
};int main() {std::shared_ptr<A> a = std::make_shared<A>();std::shared_ptr<B> b = std::make_shared<B>();a->b_ptr = b;b->a_ptr = a;return 0;
}

在這個例子中,B 持有 Astd::weak_ptr,避免了循環引用。

3.2觀察但不擁有對象

當一個對象需要被多個組件觀察,但這些組件不需要擁有對象時,可以使用 std::weak_ptr。例如,一個觀察者模式中,觀察者可以持有被觀察對象的 std::weak_ptr,這樣即使觀察者仍然存在,也不會阻止被觀察對象的銷毀。

3.3緩存場景

在某些緩存場景中,可以使用 std::weak_ptr 來存儲對對象的弱引用。當對象被銷毀時,緩存中的 std::weak_ptr 會自動失效,避免了對已銷毀對象的訪問。

4、注意事項

  1. 線程安全

    • std::weak_ptr 的操作(如 lock()expired() 等)是線程安全的,因為它們都是通過控制塊中的原子操作來實現的。
  2. 生命周期管理

    • 使用 std::weak_ptr 時,需要注意對象的生命周期。雖然 std::weak_ptr 不會阻止對象的銷毀,但在訪問對象時,必須確保對象仍然存在。
  3. 性能開銷

    • std::weak_ptr 的使用會帶來一定的性能開銷,因為它需要維護弱引用計數。在性能敏感的場景中,需要權衡使用 std::weak_ptr 的利弊。

總之,std::weak_ptr 是一種非常有用的智能指針,它通過與 std::shared_ptr 共享控制塊,提供了對對象的弱引用。它可以用于解決循環引用問題、觀察對象以及緩存場景等。在使用時,需要注意對象的生命周期和性能開銷。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73317.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73317.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73317.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2024年認證杯SPSSPRO杯數學建模B題(第二階段)神經外科手術的定位與導航全過程文檔及程序

2024年認證杯SPSSPRO杯數學建模 B題 神經外科手術的定位與導航 原題再現&#xff1a; 人的大腦結構非常復雜&#xff0c;內部交織密布著神經和血管&#xff0c;所以在大腦內做手術具有非常高的精細和復雜程度。例如神經外科的腫瘤切除手術或血腫清除手術&#xff0c;通常需要…

嘗試在軟考62天前開始成為軟件設計師-信息系統安全

安全屬性 保密性:最小授權原則(能干活的最小權限)、防暴露(隱藏)、信息加密、物理保密完整性(防篡改):安全協議、校驗碼、密碼校驗、數字簽名、公證 可用性:綜合保障( IP過濾、業務流控制、路由選擇控制、審計跟蹤)不可抵賴性:數字簽名 對稱加密 DES :替換移位 3重DESAESR…

Rocky9.5基于sealos快速部署k8s集群

首先需要下載 Sealos 命令行工具&#xff0c;sealos 是一個簡單的 Golang 二進制文件&#xff0c;可以安裝在大多數 Linux 操作系統中。 以下是一些基本的安裝要求&#xff1a; 每個集群節點應該有不同的主機名。主機名不要帶下劃線。 所有節點的時間需要同步。 需要在 K8s …

G口服務器和普通服務器之間的區別

今天小編主要來為大家介紹一下G口服務器和普通服務器之間的區別&#xff01; 首先&#xff0c;從硬件配置上看&#xff0c;普通服務器通常都會配備中央處理器、內存和硬盤等基本的硬件配置&#xff0c;能夠適用于各種應用程序和服務&#xff1b;G口服務器除了基礎的硬件配置還增…

Cursor軟件如何刷新機器碼流程

一.退出Cursor軟件賬號 打開Cursor軟件&#xff0c;點擊設置-->General-->Account-->Log out,現將Cursor軟件上登錄的賬戶退出。 二.將Cursor官網上登錄的Cursor賬戶也清空掉 點擊頭像--> ACCOUNT SETTINGS -->Account-->Advanced-->Delete Account-->…

類與對象(中)(詳解)

【本節目標】 1. 類的6個默認成員函數 2. 構造函數 3. 析構函數 4. 拷貝構造函數 5. 賦值運算符重載 6. const成員函數 7. 取地址及const取地址操作符重載 1.類的6個默認成員函數 如果一個類中什么成員都沒有&#xff0c;簡稱為空類。 空類中真的什么都沒有嗎&…

開發語言漫談-groovy

groovy是一門腳本語言&#xff0c;在前期的腳本語言中簡單介紹了下。現在再深入介紹下&#xff0c;因為它是本平臺上選用的腳本語言。所謂腳本語言就是不用編譯&#xff0c;直接執行。這種特色非常適合做嵌入編程&#xff0c;即編即用。我們知道平臺后臺的業務開發語言是Java&a…

React+Ant Design的Layout布局實現暗黑模式切換

目錄 效果預覽完整代碼我遇到的BUG問題代碼BUG1&#xff1a;暗黑模式下內容區不變成深色BUG2&#xff1a;光亮模式下的左右區域是深色 補充知識ConfigProvider是什么&#xff1f;Ant Design中的theme如何使用&#xff1f;theme 配置的常見字段主題算法通過 useToken 獲取主題 效…

TCP 三次握手與四次揮手過程

TCP 作為一種面向連接的、可靠的傳輸層協議&#xff0c;其連接管理機制對于保障數據的可靠傳輸至關重要。 三次握手&#xff08;建立連接&#xff09; 三次握手是 TCP 建立連接時所采用的機制&#xff0c;其目的在于確保客戶端和服務器雙方都具備發送和接收數據的能力&#x…

【線程安全的單例模式和STL是否是線程安全/智能指針是否是線程安全】

文章目錄 一、單例模式的特點二、餓漢模式實現單例三、懶漢模式實現單例四、STL線程安全嗎&#xff1f;五、智能指針線程安全嗎&#xff1f; 一、單例模式的特點 一個類&#xff0c;只應該實例化了一個對象&#xff0c;就是單例。 二、餓漢模式實現單例 舉個餓漢模式的例子&…

力扣DAY24 | 熱100 | 回文鏈表

前言 簡單 √ 是反轉鏈表的衍生題&#xff0c;很快寫完了。不過沒考慮到恢復鏈表結構的問題。 題目 給你一個單鏈表的頭節點 head &#xff0c;請你判斷該鏈表是否為回文鏈表。如果是&#xff0c;返回 true &#xff1b;否則&#xff0c;返回 false 。 示例 1&#xff1a; 輸…

【GL010】C++

1.C中的const關鍵字有哪些用法&#xff1f; 1.修飾變量&#xff1a;表示變量的值不可修改。 const int a 10; 2.修飾指針&#xff1a; const int* p&#xff1a; // 指針指向的內容不可修改。 int* const p&#xff1a; // 指針本身不可修改。 const int* const…

金融行業 UE/UI 設計:解鎖高效體驗,重塑行業界面

在數字化浪潮中&#xff0c;金融行業的競爭日益激烈&#xff0c;用戶體驗&#xff08;UE&#xff09;和用戶界面&#xff08;UI&#xff09;設計成為企業脫穎而出的關鍵。蘭亭妙微憑借豐富的經驗和創新的方法&#xff0c;為金融行業打造了一套行之有效的 UE/UI 解決方案&#x…

C語言字符函數,字符串函數以及內存函數

那么博主寫這一片博客的目的就是為下一篇c的string類做鋪墊&#xff0c;那么下面就請期待博主的下一篇文章吧。 目錄 1.字符函數 2.字符串函數&#xff08;均在string.h頭文件中&#xff09; strlen的使用和模擬實現 strcpy 的使用和模擬實現 strcat 的使用和模擬實現 s…

_DISPATCHER_HEADER結構中的WaitListHead和_KWAIT_BLOCK的關系

第一部分&#xff1a; // // Wait block // // begin_ntddk begin_wdm begin_nthal begin_ntifs begin_ntosp typedef struct _KWAIT_BLOCK { LIST_ENTRY WaitListEntry; struct _KTHREAD *RESTRICTED_POINTER Thread; PVOID Object; struct _KWAIT_BLOCK *R…

flutter 自定義控件RenderObjectWidget使用

CustomWidget的自定義組件的注釋還是比較清晰的 參考文檔Flutter實戰 import package:flutter/cupertino.dart; import package:flutter/gestures.dart; import package:flutter/material.dart; /* * 如果組件不會包含子組件&#xff0c;則我們可以直接繼承自 LeafRenderObject…

機器視覺場景應用中,有沒有超景深的工業鏡頭

在機器視覺領域,確實存在具有超景深特性的工業鏡頭,這類鏡頭通過特殊的光學設計或技術手段,能夠顯著擴大清晰成像的縱向范圍,從而滿足復雜檢測場景中對多平面物體清晰成像的需求。以下是相關技術要點及典型鏡頭類型: 1. 遠心鏡頭 遠心鏡頭是超景深鏡頭的典型代表,其特點包…

【Linux】同步原理剖析及模擬BlockQueue生產消費模型

&#x1f4e2;博客主頁&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客倉庫&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;歡迎點贊 &#x1f44d; 收藏 ?留言 &#x1f4dd; 如有錯誤敬請指正&#xff01; &…

光流 | 基于KLT算法的人臉檢測與跟蹤原理及公式,算法改進,matlab代碼

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 人臉檢測與跟蹤 一、KLT算法原理與分析1. 核心思想2. 數學模型二、人臉…

<數據集>軌道異物識別數據集<目標檢測>

數據集下載鏈接&#xff1a;https://download.csdn.net/download/qq_53332949/90527370 數據集格式&#xff1a;VOCYOLO格式 圖片數量&#xff1a;1659張 標注數量(xml文件個數)&#xff1a;1659 標注數量(txt文件個數)&#xff1a;1659 標注類別數&#xff1a;6 標注類別…