從C++開始的編程生活(8)——內部類、匿名對象、對象拷貝時的編譯器優化和內存管理

前言

本系列文章承接C語言的學習,需要有C語言的基礎才能學會哦~
第8篇主要講的是有關于C++的內部類匿名對象對象拷貝時的編譯器優化內存管理
C++才起步,都很簡單!!


目錄

前言

內部類

性質

匿名對象

性質

※對象拷貝時的編譯器優化

內存管理

內存分區

?編輯

內核空間

靜態區/數據段

常量區/代碼段

虛擬進程地址空間

動態內存管理函數

C++內存管理

基本語法

operator new和operator delete函數

new和delete的原理

定位new表達式(placement-new)

※內存池(了解即可,后面會深度學)


內部類

一個類定義在另一個類里,這個類就是內部類。

//簡單代碼
class A
{public:private:class B{private:int _b;}
}

性質

內部類默認是外部類的友元
本質是一種封裝方式。若類B實現出來是為了給類A使用,那么可以把B設置為A的內部類。
內部類受訪問限定符限制,被privact和protect修飾的內部類只能被外部類使用。

匿名對象

沒有標識符標識的對象為匿名對象,反之為有名對象。

//有名對象,d1為其名
Date d1(1999,9,9);
//匿名對象
Date(2000,1,1);

性質

匿名對象的生命周期只有一行代碼。也就是匿名對象構造后,下一步就會被析構(一次性筷子)。
②匿名對象具有常性,只能被const引用
被const引用后,匿名對象的生命周期被延長至與該引用同步。

※對象拷貝時的編譯器優化

現代編譯器會在不影響代碼正確性的情況下,提高效率,在底層進行優化實現。
不同的編譯器,優化方式不同,以下優化方式以VS2019的debug為例。
越新的編譯器,優化越好,甚至會有跨多行合并優化代碼。

例1:隱式類型轉換

A aa1 = 1;//隱式類型轉換

語法上:該隱式類型轉換先以1為參數構造臨時對象,在將臨時對象拷貝構造給aa1。
實際上:直接以1為參數構造新對象aa1。
從而減少對內存的使用,提高代碼運行效率。

例2:傳值傳參

void func(A aa)
{//·······
}
int main()
{func(1)return 0;
}

語法上:該傳值傳參先以1為參數構造臨時對象,在將臨時對象拷貝構造給aa,然后傳入func。
實際上:直接以1為參數構造對象aa傳入func。
從而減少對內存的使用,提高代碼運行效率。

例3:傳值返回

A f2()
{A aa;return aa
}int main()
{A aa2 = f2();return 0;
}

語法上:構造f2函數局部域的一個對象aa,然后返回aa時將aa拷貝構造為臨時對象,接著臨時對象在拷貝構造給aa2。(構造->拷貝->拷貝)。
實際上:構造f2函數局部域的一個對象aa,再直接拷貝給aa2。

內存管理

內存分區

內存分區主要分為四個區(還有其他不常用的區,這里省去):棧區、堆區、靜態區和常量區

內核空間

用戶代碼,不可以讀寫。

局部變量,參數,返回值,對象,函數調用等等要在棧區開辟棧幀,主要存儲臨時的、局部的變量(棧區占比不大,M為單位)。棧向下增長,越后開辟的空間地址越小。

malloc、new等動態內存管理開辟的空間,在堆區(占比較大,以G為單位)。堆向上增長,越后開辟的空間地址越大(可能會在動態內存管理時被打亂順序)

靜態區/數據段

全局數據和靜態數據放在靜態區。

常量區/代碼段

存放常量和編譯完成的指令

虛擬進程地址空間

地址空間是虛擬的,需要頁表等算法進行映射,這個部分知識涉及操作系統。

int a;
static int b = 1;
int main()
{int num[] = {1,2,3,4};static int c = 1;char arr[] = "abcdefg";const char* p1 = "abcdefg";char* p2 = (char*)malloc(sizeof(char) * 10);
}

如上代碼
a、b、c存放在靜態區
num、arr數組存放在棧區
p2存放在堆區
“abcdefg”存放在常量區

動態內存管理函數

C語言動態內存管理函數 malloc / calloc / realloc / free 依舊可以使用

tips:malloc / calloc / realloc的區別?------>calloc會在malloc的基礎上,初始化開辟空間;realloc重新分配更多的空間,也覆蓋malloc的功能。

C++內存管理

C++有新的方式進行內存管理,使用 new / delete 操作符進行內存管理。

基本語法

int main()
{//動態申請1個int類型空間int *ptr1 = new int;//動態申請1個int類型空間,并初始化為10int *ptr2 = new int(10);//釋放開辟的int類型空間delete ptr1;delete ptr2;//動態申請3個int類型的空間int ptr3 = new int[3];//動態申請3個int類型的空間,并依次初始化為1,2,3int ptr4 = new int[3]{1,2,3};//動態申請5個int類型的空間,并依次初始化為1,2,3,為指定初始化的空間,默認初始化為0int ptr5 = new int[5]{1,2,3};//釋放開辟的int類型數組delete[] ptr3;delete[] ptr4;delete[] ptr5;return 0;
}

以上為new和delete的使用,改為malloc和free基本沒有區別。

而new開辟自定義類型:

//malloc開辟
A* p1 = (A*)malloc(sizeof(A));
//new開辟
A* p2 = new A;
A* p3 = new A(10);
A* p4 = new A[10];//申請空間,構造10次
A* p5 = new A[2]{1,2};//申請空間,構造2次
A* p6 = new A[2]{p2,p3};//申請空間,構造2次

區別:
new之于malloc,不只是申請空間,還會調用其默認構造函數。
錯誤時不返回NULL,而是拋出異常。
不需要手動填入申請空間大小

而delete釋放自定義類型:

delete p2;
delete p3;
delete[] p4;//申請空間,析構10次
delete[] p5;//申請空間,析構2次
delete[] p6;//申請空間,析構2次

區別:delete之于free,不只是釋放空間,還會調用其析構函數。

綜上,對于自定義類型,還是優先使用new和delete。

operator new和operator delete函數

這不是對操作符new和delete的重載,它們實際上是兩個全局函數使用new和delete時,在底層會調用相應的全局函數

在底層源碼中,new實際上是對malloc的再次擴展封裝。
malloc錯誤后會拋出一個nullptr,new會遇到malloc拋出的空指針后,首先執行用戶提供的應對措施,如果不提供,就拋出一個異常。(異常為后面的內容,了解即可)。

在底層源碼中,delete實際上是對free的再次擴展封裝。
進行錯誤檢查等處理后,再通過free釋放空間

operator new和operator delete也可以直接調用。

new和delete的原理

調用new:①調用operator new函數,開辟空間。②若開辟自定義類型空間,最后依次調用其默認構造函數。

調用delete:①若是釋放自定義類型空間,首先依次調用其析構函數。②調用operator delete函數,釋放空間。

定位new表達式(placement-new)

作用是在已分配的原始內存空間調用構造函數初始化一個對象。

A *p1 = (A*)operator new(sizeof(A));
//new + 需構造的指針 + 對象類型 + 初始化參數
new(p1)A(10);

為什么要這樣做呢?因為不是new開辟的對象,不可以直接初始化,必須要用這種格式

p1->A(10);//錯誤的

但是,析構可以直接調用。

p1->~A();

※內存池(了解即可,后面會深度學)

從堆區里一次性開辟出較大的內存空間作為內存池,通過數據結構管理起來,申請空間從內存池取出,可以減少頻繁申請堆區,因為在堆區只能依次申請空間,效率低。

?~~本文完結!!感謝觀看!!接下來更精彩!!歡迎來我博客做客~~?

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

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

相關文章

MT5追大速率回測BUG

將MT5策略測試器中的回測速率調到最大(最快速度),**確實非常容易導致出現不符合策略邏輯的秒級成交(閃電交易)**。這并非MT5的“bug”,而是由**回測引擎的工作方式**與**策略代碼的編寫方法**在高速運行下不匹配所導致的。 --- ### 為什么最大速率會導致問題? MT5回測…

[數據結構——lesson10.堆及堆的調整算法]

引言 上節我們學習完二叉樹后[數據結構——lesson9.二叉樹],這節我們將學習數據結構——堆 學習目標 1.堆的概念及結構 堆是一種特殊的完全二叉樹結構,在計算機科學和數據結構中廣泛應用,特別是在堆排序算法和優先隊列的實現中,…

九識智能與北控北斗合作研發的L4級燃氣超微量高精準泄漏檢測無人車閃耀服貿會,守護城市安全

2025年9月10日至14日,2025年中國國際服務貿易交易會將于北京首鋼園舉辦。在這場國際盛會上,九識智能與北京北控北斗科技投資有限公司(以下簡稱“北控北斗”)合作研發的L4級燃氣超微量高精準泄漏檢測無人車及相關系統解決方案&…

【C語言入門】手把手教你實現順序棧

棧是計算機科學中最基礎且重要的數據結構之一,它遵循"后進先出"(LIFO)的原則。想象一下一疊盤子,你只能從最上面取放,這就是棧的直觀體現。本文將用C語言帶你一步步實現一個順序棧,即使你是編程小…

北斗導航 | ARAIM(高級接收機自主完好性監測)算法在民航LPV-200進近中的具體實現流程

要詳細說明ARAIM(高級接收機自主完好性監測)算法在民航LPV-200進近中的具體實現流程,需結合ARAIM的核心邏輯(多星座融合、多假設解分離、風險優化分配)與LPV-200的嚴格要求(垂直保護級VPL≤35米、垂直告警限VAL=35米、有效監測門限EMT≤15米等),以下是 step-by-step 的…

AIPex:AI + 自然語言驅動的瀏覽器自動化擴展

AIPex:AI + 自然語言驅動的瀏覽器自動化擴展 引言 一、快速上手 1.1 安裝AIPex擴展 1.2 首次配置 1.3 界面介紹 第二章:30+工具詳解 2.1 標簽頁管理工具集 ??? **get_all_tabs - 全局標簽頁概覽** ?? **switch_to_tab - 智能標簽頁切換** ?? **標簽頁批量操作** ?? …

機器學習模型可信度與交叉驗證:通俗講解

先從一個故事說起:農場里的火雞科學家,觀察了一年發現“每天上午11點必有食物”,結果感恩節當天,它沒等到食物,反而成了人類的食物。這個故事告訴我們:只靠過去的經驗下結論,很可能出錯——機器…

HTML5和CSS3新增的一些屬性

1、HTML5新增特性這些新特性都有兼容性問題&#xff0c;基本是IE9以上版本瀏覽器才支持1&#xff09;新增語義化標簽2&#xff09;新增多媒體標簽音頻&#xff1a;<audio>視頻&#xff1a;<video>&#xff08;1&#xff09;視頻<video>---盡量使用mp4格式<…

Redis的RedLock

RedLock算法深度解析RedLock是Redis作者針對分布式環境設計的多節點鎖算法&#xff0c;核心目標是解決單點Redis在分布式鎖場景中的可靠性缺陷。傳統方案的局限性單節點Redis鎖的問題單點故障&#xff1a;單個Redis實例宕機導致所有鎖服務不可用可靠性不足&#xff1a;無法保證…

SpringMVC @RequestMapping的使用演示和細節 詳解

目錄 一、RequestMapping是什么&#xff1f; 二、RequestMapping 的使用演示 1.RequestMapping在方法上的使用&#xff1a; 2.RequestMapping同時在類和方法上使用&#xff1a; 3.RequestMapping指定請求參數&#xff1a; 4.RequestMapping使用Ant風格URL&#xff1a; 5.Requ…

flutter項目 -- 換logo、名稱 、簽名、打包

1、換logo, 透明底&#xff0c;下面5個尺寸&#xff0c;需要UI設計2、換名沒配置型的改名方式如下 打開app/src/main/AndroidManifest.xml3、簽名 運行 flutter doctor -vD:\project\Apk\keystore 自己建立的keystore文件夾&#xff0c; 注意命令后是 megoai-release-key(自…

【貪心算法】day9

&#x1f4dd;前言說明&#xff1a; 本專欄主要記錄本人的貪心算法學習以及LeetCode刷題記錄&#xff0c;按專題劃分每題主要記錄&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代碼&#xff1b;&#xff08;2&#xff09;優質解法 優質代碼&#xff1b;&#xff…

linux C 語言開發 (八) 進程基礎

文章的目的為了記錄使用C語言進行linux 開發學習的經歷。開發流程和要點有些記憶模糊&#xff0c;趕緊記錄&#xff0c;防止忘記。 相關鏈接&#xff1a; linux C 語言開發 (一) Window下用gcc編譯和gdb調試 linux C 語言開發 (二) VsCode遠程開發 linux linux C 語言開發 (…

從零學算法1094

1094.拼車 車上最初有 capacity 個空座位。車 只能 向一個方向行駛&#xff08;也就是說&#xff0c;不允許掉頭或改變方向&#xff09; 給定整數 capacity 和一個數組 trips , trips[i] [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi 乘客&#xff0c;接他…

B2B企業營銷型AI Agent服務商推薦:誰更專業?如何選型?

一、引言&#xff1a;為什么B2B企業需要營銷型AI Agent&#xff1f;在當前競爭激烈的B2B市場中&#xff0c;企業普遍面臨幾大挑戰&#xff1a;線索獲取難&#xff1a;獲客成本持續上升&#xff0c;高質量線索難以篩選。銷售周期長&#xff1a;從初步接觸到簽單&#xff0c;往往…

算法-雙指針5.6

目錄 &#x1f33f;力扣611-有效三角形得個數 &#x1f9ca;題目鏈接&#xff1a;https://leetcode.cn/problems/valid-triangle-number/description/ &#x1f9ca;題目描述&#xff1a;?編輯 &#x1f9ca;解題思路&#xff1a; &#x1f9ca;解題代碼&#xff1a; &a…

超參數自動化調優指南:Optuna vs. Ray Tune 對比評測

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;注冊即送-H卡級別算力&#xff0c;80G大顯存&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生更享專屬優惠。 引言&#xff1a;從"手動煉丹"到"自動化…

軟考-局域網基礎考點總結

這篇文章用于整理軟考網絡相關的知識點&#xff0c;囊括了詳細的局域網基礎的考點&#xff0c;能夠讓你認真備考&#xff0c;基礎知識一網打盡&#xff0c;讓后續的學習更加通暢~ 第一部分&#xff1a;OSI七層參考模型 OSI(Open System Interconnection)模型是一個理論框架&am…

Node.js核心模塊介紹

1. fs 模塊fs&#xff08;File System&#xff09;模塊允許對文件系統進行操作&#xff0c;提供了文件讀寫、文件夾操作等功能。fs 支持同步和異步兩種 API。1.1. 常用方法讀取文件&#xff1a;異步: fs.readFile()同步: fs.readFileSync()寫入文件&#xff1a;異步: fs.writeF…

緩存三大劫攻防戰:穿透、擊穿、雪崩的Java實戰防御體系(二)

第二部分&#xff1a;緩存擊穿——熱點key過期引發的“DB瞬間高壓” 緩存擊穿的本質是“某個熱點key&#xff08;高并發訪問&#xff09;突然過期”&#xff0c;導致大量請求在同一時間穿透緩存&#xff0c;集中沖擊DB&#xff0c;形成“瞬間高壓”。 案例3&#xff1a;電商秒殺…