C++高頻知識點(十)

文章目錄

  • 46. 智能指針是什么?怎么使用?
    • 1. std::unique_ptr
    • 2. std::shared_ptr
    • 3. std::weak_ptr
  • 47. 什么是野指針?
    • 1. 使用已釋放的指針
    • 2. 未初始化的指針
    • 3. 指針超出作用域
    • 如何避免野指針
      • 1. 立即將指針置空
      • 2. 初始化指針
      • 3. 使用智能指針
      • 4. 避免返回局部變量的地址
  • 48. 虛函數的機制是怎么實現的?
    • 機制實現步驟
  • 49. nullptr和null的區別?
  • 50. 什么是二叉搜索樹?實際應用有什么?

46. 智能指針是什么?怎么使用?

C++11標準庫引入了三種主要的智能指針:std::unique_ptr、std::shared_ptr和std::weak_ptr。

1. std::unique_ptr

std::unique_ptr是一個獨占所有權的智能指針,它確保同一時間內只有一個指針可以擁有某個對象的所有權。適合用于一個對象只能被一個指針擁有的情況。

#include <iostream>
#include <memory>class MyClass {
public:MyClass() {std::cout << "MyClass Constructor" << std::endl;}~MyClass() {std::cout << "MyClass Destructor" << std::endl;}void display() {std::cout << "Display method of MyClass" << std::endl;}
};int main() {// 創建一個unique_ptr對象,管理MyClass實例std::unique_ptr<MyClass> ptr1(new MyClass());ptr1->display(); // 使用智能指針調用方法// 轉移所有權std::unique_ptr<MyClass> ptr2 = std::move(ptr1);if (!ptr1) {std::cout << "ptr1 is now null" << std::endl;}ptr2->display(); // 使用新的智能指針調用方法// ptr2超出作用域,MyClass對象自動銷毀return 0;
}

在這里插入圖片描述

2. std::shared_ptr

std::shared_ptr是一個共享所有權的智能指針,可以被多個指針共享。它通過引用計數來管理對象的生命周期,當最后一個std::shared_ptr銷毀時,對象才會被釋放。

#include <iostream>
#include <memory>class MyClass {
public:MyClass() {std::cout << "MyClass Constructor" << std::endl;}~MyClass() {std::cout << "MyClass Destructor" << std::endl;}void display() {std::cout << "Display method of MyClass" << std::endl;}
};int main() {// 創建一個shared_ptr對象,管理MyClass實例std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();{// 創建第二個shared_ptr,共享相同的對象std::shared_ptr<MyClass> ptr2 = ptr1;ptr2->display(); // 使用智能指針調用方法std::cout << "ptr2 going out of scope" << std::endl;} // ptr2超出作用域,但對象未銷毀,因為ptr1還在使用ptr1->display(); // 使用剩余的智能指針調用方法// ptr1超出作用域,MyClass對象自動銷毀return 0;
}

在這里插入圖片描述

3. std::weak_ptr

std::weak_ptr是一個不擁有所有權的智能指針,它是為了配合std::shared_ptr使用,解決循環引用問題std::weak_ptr不能直接訪問對象,需要先轉換為std::shared_ptr。

#include <iostream>
#include <memory>class MyClass {
public:std::shared_ptr<MyClass> other;MyClass() {std::cout << "MyClass Constructor" << std::endl;}~MyClass() {std::cout << "MyClass Destructor" << std::endl;}void display() {std::cout << "Display method of MyClass" << std::endl;}
};int main() {std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();std::shared_ptr<MyClass> ptr2 = std::make_shared<MyClass>();// 使用weak_ptr避免循環引用ptr1->other = ptr2;ptr2->other = ptr1;ptr1->display();ptr2->display();// ptr1和ptr2超出作用域,MyClass對象自動銷毀return 0;
}

在這里插入圖片描述
如果要使用 std::weak_ptr 來避免循環引用,可以對 MyClass 的 other 成員使用 std::weak_ptr,而不是 std::shared_ptr。這樣做可以防止形成循環引用,從而避免對象無法正確釋放的問題。下面是修改后的示例代碼:

#include <iostream>
#include <memory>class MyClass {
public:std::weak_ptr<MyClass> other;  // 使用 weak_ptr 避免循環引用MyClass() {std::cout << "MyClass Constructor" << std::endl;}~MyClass() {std::cout << "MyClass Destructor" << std::endl;}void display() {std::cout << "Display method of MyClass" << std::endl;}
};int main() {std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();std::shared_ptr<MyClass> ptr2 = std::make_shared<MyClass>();// 使用 weak_ptr 來避免循環引用ptr1->other = ptr2;ptr2->other = ptr1;ptr1->display();ptr2->display();// ptr1 和 ptr2 超出作用域,MyClass 對象會正確釋放return 0;
}

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
當然,以下是一個總結 std::unique_ptr、std::shared_ptr 和 std::weak_ptr 三種智能指針特點的表格:

在這里插入圖片描述
在這里插入圖片描述

47. 什么是野指針?

野指針(Dangling Pointer)是指那些指向已經釋放或未分配內存的指針。使用野指針會導致未定義行為,包括程序崩潰、數據損壞等嚴重問題。

以下是關于野指針的詳細說明。

野指針的成因

1. 使用已釋放的指針

當一個指針指向的內存被釋放后,指針仍然保留原來的地址,此時指針變成野指針。

int* p = new int(10);
delete p;
// 此時,p成為野指針
// *p = 20; // 未定義行為,可能導致程序崩潰

2. 未初始化的指針

未初始化的指針默認指向一個不確定的地址,直接使用這種指針會導致野指針問題。

int* p; // p未初始化,指向一個隨機地址
// *p = 10; // 未定義行為,可能導致程序崩潰

3. 指針超出作用域

當指針指向的內存區域超出其作用域后,指針變成野指針。

int* foo() {int x = 10;return &x; // 返回局部變量的地址
}
// int* p = foo(); // p成為野指針,x已超出作用域

如何避免野指針

1. 立即將指針置空

在釋放內存后,立即將指針置為空指針(nullptr),避免使用野指針。

int* p = new int(10);
delete p;
p = nullptr; // 避免使用野指針

2. 初始化指針

聲明指針時,立即進行初始化。如果不知道該指向哪里,可以將其初始化為nullptr。

int* p = nullptr; // 初始化指針
// *p = 10; // 編譯錯誤,安全

3. 使用智能指針

智能指針(如std::unique_ptr和std::shared_ptr)可以自動管理內存,防止野指針。

#include <memory>void example() {std::unique_ptr<int> p = std::make_unique<int>(10);// 不需要手動釋放內存
}

4. 避免返回局部變量的地址

不要返回局部變量的地址,可以使用動態分配或者將結果通過參數返回。

int* foo() {int* x = new int(10); // 動態分配內存return x;
}void foo(int& x) {x = 10; // 通過參數返回
}

48. 虛函數的機制是怎么實現的?

在這里插入圖片描述

機制實現步驟

在這里插入圖片描述

#include <iostream>class Base {
public:virtual void show() {std::cout << "Base class show function\n";}
};class Derived : public Base {
public:void show() override {std::cout << "Derived class show function\n";}
};int main() {Base* b = new Derived();b->show(); // 將調用Derived類的show函數delete b;return 0;
}

在這里插入圖片描述

49. nullptr和null的區別?

在這里插入圖片描述
由于NULL是一個整數常量,使用NULL可能導致一些類型不安全的問題。例如:

void foo(int) { std::cout << "int" << std::endl; }
void foo(void*) { std::cout << "void*" << std::endl; }int main() {foo(NULL); // 調用 foo(int),而不是 foo(void*)cout<<NULL<<endl; //這里輸出0;return 0;
}

現在編譯器能發現問題,但是還是避開寫NULL
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

50. 什么是二叉搜索樹?實際應用有什么?

在這里插入圖片描述
在這里插入圖片描述
這種性質使得在BST中查找、插入和刪除元素非常高效,平均時間復雜度為 O(log n)。

在這里插入圖片描述
6. 自動補全和拼寫檢查:

  • 使用BST實現字符串的前綴樹,用于自動補全和拼寫檢查。

之后我會持續更新,如果喜歡我的文章,請記得一鍵三連哦,點贊關注收藏,你的每一個贊每一份關注每一次收藏都將是我前進路上的無限動力 !!!↖(▔▽▔)↗感謝支持!

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

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

相關文章

c#中Random類、DateTime類、String類

C# 中 Random 類分析Random 類用于生成偽隨機數&#xff0c;位于 System 命名空間。它的核心機制是基于一個種子值 (seed)&#xff0c;通過算法生成看似隨機的數列。相同種子會生成相同的隨機數序列&#xff0c;這在需要可重現的隨機場景中很有用。核心特點種子與隨機性默認構造…

Vscode 下載遠程服務器失敗解決方法

今天在使用 vscode 連接遠程主機時&#xff0c;突然再次遇到這個問題&#xff0c;按照以往的經驗&#xff0c;直接按照這個博主的文章其實就能解決&#xff0c;但是不知道為什么&#xff0c;今天這個方案失效了&#xff0c;然后卸載安裝服務器和本機的vscode什么的也都試過了&a…

【算法】貪心算法:檸檬水找零C++

文章目錄前言題目解析算法原理代碼示例策略證明前言 題目的鏈接&#xff0c;大家可以先試著去做一下再來看一下思路。 860. 檸檬水找零 - 力扣&#xff08;LeetCode&#xff09; 題目解析 首先我們要認真去拿到題目中的關鍵有用信息。 認真的去閱讀題目給的示例&#xff0c;然…

27.【.NET8 實戰--孢子記賬--從單體到微服務--轉向微服務】--單體轉微服務--幣種服務(一)

從本篇文章開始&#xff0c;我們將用兩篇內容詳細介紹幣種服務的實現。幣種服務本身結構較為簡單&#xff0c;核心功能包括內置幣種的初始化、幣種匯率的同步以及匯率的查詢。在本篇中&#xff0c;我們將重點講解如何實現內置幣種的初始化功能&#xff0c;為后續的服務打下基礎…

(2)從零開發 Chrome 插件:實現 API 登錄與本地存儲功能

從零開發 Chrome 插件&#xff1a;實現 API 登錄與本地存儲功能 Chrome 插件作為瀏覽器功能的重要擴展&#xff0c;能極大提升用戶的工作效率。本文將以一個「登錄功能插件」為例&#xff0c;帶你從零構建一個可調用 API 驗證身份、并將用戶信息存儲在本地的 Chrome 插件。 基…

Flink時間窗口詳解

一、引言在大數據流處理的領域中&#xff0c;Flink 的時間窗口是一項極為關鍵的技術&#xff0c;想象一下&#xff0c;你要統計一個電商網站每小時的訂單數量。由于訂單數據是持續不斷產生的&#xff0c;這就形成了一個無界數據流。如果沒有時間窗口的概念&#xff0c;你就需要…

寬帶接入,網線插入電腦的經驗

現在一般家里安裝移動寬帶&#xff0c;都會提供四個千兆接口的光貓路由器&#xff0c;但是要注意了 首先網線的兩端看起來一樣&#xff0c;實際上并不是&#xff0c;如果發現連接不成功&#xff0c;那么就要換一頭重新嘗試&#xff0c; 一般像說什么自動DHCP啊&#xff0c;因為…

crmeb多門店對接拉卡拉支付小程序聚合收銀臺集成全流程詳解

一、商戶注冊與配置??注冊支付平臺賬號??&#xff1a;在拉卡拉開放平臺注冊商戶賬號&#xff08;私信聯系注冊&#xff09;??創建應用??&#xff1a;獲取小程序應用ID(AppID)??配置支付參數??&#xff1a;商戶號(MID)終端號(TID)API密鑰支付回調地址二、配置拉卡拉…

C#將樹圖節點展示到NetronLight圖表中

之前寫過NetronLight開源框架 C#使用開源框架NetronLight繪制流程圖-CSDN博客 我們這里將TreeView樹圖的節點內容展示到NetronLight圖表中&#xff0c;按照樹的層次【深度Level】展示 新建窗體應用程序ShowTreeNodeToDiagram&#xff0c;將默認的Form1重命名為FormShowNode&…

精密模具大深徑比微孔尺寸檢測方案 —— 激光頻率梳 3D 輪廓檢測

引言精密模具中大深徑比微孔&#xff08;深徑比&#xff1e;20:1&#xff0c;孔徑&#xff1c;1mm&#xff09;的尺寸精度直接影響注塑件、電子元件等產品的成型質量。此類微孔具有孔徑小、深度大、表面質量要求高&#xff08;Ra≤0.1μm&#xff09;等特點&#xff0c;傳統檢測…

defer學習指南

一、源頭&#xff1a;早期管理資源&#xff08;如數據庫連接、鎖、文件句柄、網絡連接&#xff09;和狀態清理異常麻煩。 必須在每個可能的返回點&#xff08;return、err、panic&#xff09;手動重復清理代碼&#xff0c;極易遺漏且打斷主要邏輯思路&#xff01;像Java語言雖然…

NLP_知識圖譜_大模型——個人學習記錄

1. 自然語言處理、知識圖譜、對話系統三大技術研究與應用 https://github.com/lihanghang/NLP-Knowledge-Graph 深度學習-自然語言處理(NLP)-知識圖譜&#xff1a;知識圖譜構建流程【本體構建、知識抽取&#xff08;實體抽取、 關系抽取、屬性抽取&#xff09;、知識表示、知…

linux:進程詳解(1)

目錄 ?編輯 1.進程基本概念與基本操作 1.1 概念 1.2 描述進程-PCB 1.2.1PCB的基本概念 1.2.2 task_ struct 1.2.3 查看進程 2.進程狀態 2.1 Linux內核源碼展示 2.2 進程狀態查看 ?編輯 2.3 Z(zombie)-僵?進程 2.4 僵尸進程的危害 2.5 孤兒進程 3.進程優先級 …

碳中和目標下的全球產業鏈重構:深度解析與未來路徑

引言&#xff1a;氣候臨界點與產業鏈的系統性風險2023年&#xff0c;全球平均氣溫較工業化前上升1.2℃&#xff0c;南極冰蓋年消融量達1500億噸&#xff0c;極端天氣事件導致的經濟損失占全球GDP的2.3%。這一系列數據背后&#xff0c;暴露出傳統產業鏈的致命缺陷——其設計邏輯…

FPGA實現SDI轉LVDS視頻發送,基于GTX+OSERDES2原語架構,提供2套工程源碼和技術支持

目錄 1、前言工程概述免責聲明 2、相關方案推薦我已有的所有工程源碼總目錄----方便你快速找到自己喜歡的項目本博已有的 SDI 編解碼方案FPGA實現LVDS視頻收發方案 3、工程詳細設計方案工程設計原理框圖SDI 輸入設備Gv8601a 均衡器GTX 解串SMPTE SD/HD/3G SDI IP核BT1120轉RGB奇…

新手向:使用Python構建高效的日志處理系統

本文將詳細講解如何使用Python開發一個專業的日志分析工具&#xff0c;能夠自動化處理、分析和可視化各類日志文件&#xff0c;大幅提升運維效率。環境準備開發本工具需要以下環境配置&#xff1a;Python環境&#xff1a;建議Python 3.8或更高版本必要庫&#xff1a;pandas&…

大模型-量化技術

簡介 模型量化是一種重要的模型壓縮技術。其核心目標是在可控精度損失下&#xff0c;將大模型中浮點型權重&#xff08;通常為 float32 等高精度格式&#xff09;近似轉換為低精度離散值表示&#xff08;通常為 int8&#xff09;。 具體而言&#xff0c;該技術通過將模型的權重…

【C語言網絡編程】HTTP 客戶端請求(域名解析過程)

在做 C 語言網絡編程或模擬 HTTP 客戶端時&#xff0c;第一步就離不開“把域名解析為 IP 地址”這一步。很多人可能直接復制粘貼一段 gethostbyname 的代碼&#xff0c;但未必真正理解它的原理。 本篇博客將圍繞一個經典函數&#xff1a; char *host_to_ip(const char *hostna…

Node.js特訓專欄-實戰進階:16. RBAC權限模型設計

?? 歡迎來到 Node.js 實戰專欄!在這里,每一行代碼都是解鎖高性能應用的鑰匙,讓我們一起開啟 Node.js 的奇妙開發之旅! Node.js 特訓專欄主頁 專欄內容規劃詳情 我將從RBAC權限模型的基礎概念、核心組件講起,詳細闡述其設計原則、數據庫模型設計,還會結合代碼示例展示在…

mac上BRPC的CMakeLists.txt優化:解決Protobuf路徑問題

問題背景與挑戰 在構建高性能RPC框架BRPC時&#xff0c;?Protobuf依賴路徑的配置往往是開發者面臨的主要挑戰之一。原始CMake配置在尋找Protobuf庫時存在以下痛點&#xff1a; ?路徑搜索不精確?&#xff1a;默認find_library無法定位自定義安裝路徑下的Protobuf?版本兼容…