從CPU的視角看C++的構造函數和this指針

從匯編角度,清晰的去看構造函數和this指針到底是個什么東西呢?也許可以解決你的一點小疑問

首先寫一個很簡單的代碼demo:

class A{
public:int a;A(){;}void seta(int _a){a=_a;}A* getA(){return this;}
};int fun1(int px){return px;
}int main(){A aa;aa.seta(8); aa.getA();
}

mov rbp, rsp:設置新的基址指針,指向當前棧幀。

mov QWORD PTR [rbp-8], rdi:將 this 指針(存儲在 rdi 中)保存到棧上。

在seta中的部分匯編:

mov rax, QWORD PTR [rbp-8]:將 this 指針的值加載到 rax 中。

mov DWORD PTR [rax], edx:將 edx(即 _a 的值)存儲到 this->a 中。

我們從類成員函數和構造函數中都能看到 兩句關于參數的匯編,同理普通函數中px參數也有著相同的匯編,那么很顯然,對于cpu而言,this指針僅僅是一個參數而已。C++語法糖對于this做了隱藏處理,因此我們在使用的時候才會無感。

而這個有這個this往往可以認為函數的完整使用是這樣:

    A aa;aa.seta(8); ====A::seta(&aa,8) 當然這么調用是錯誤的,看著很像類靜態函數

this 指針的創建

  • 函數調用前創建:當成員函數被調用時,this 指針在調用成員函數之前被設置為當前對象的地址。也就是說,在成員函數執行之前,this 指針已經被創建并指向調用該函數的對象。

this 指針的銷毀

  • 函數調用結束后銷毀:在成員函數執行完畢并返回后,this 指針的生命周期就結束了。因為 this 只是一個指向對象的指針,當函數返回時,不再需要這個指針,函數調用上下文會自動清理這個隱式參數。

?

學習C++的友友大概率會知道這么一句話:靜態成員函數不屬于類的某個具體對象,而是屬于整個類。這意味著靜態成員函數不能訪問非靜態成員變量和成員函數,因為它們沒有 this 指針。針對這句話我們也可以通過cpu視角進行觀察

而this 指針的存在條件

  • 對象實例調用:只有當對象實例調用非靜態成員函數時,this 指針才會被傳遞給該函數。
  • 隱式參數:在非靜態成員函數內部,編譯器會自動添加一個隱式的 this 指針參數,用于引用調用該函數的對象

觀察上圖,你就會看到 靜態成員函數中沒有this指針,即也就沒法去調用相關的成員函數和數據,如果我們想要通過靜態成員函數去調用對象相關的數據,可以通過黃色框框的這種寫法。你會發現這種寫法的匯編同成員函數的匯編相同,也就是說this存的就是傳遞進去的這個對象的地址。

也就有了成員函數的完整版應該是:void setp(A* this,int p);是不是看著參數和示例第二個靜態成員函數一樣~

cpu眼中構造函數與普通函數沒有任何區別:

通過上面的匯編也能看明白,構造含有this指針,且對于cpu來說他與普通函數是相同的

派生類構造函數總會調用基類的構造函數

  • mov QWORD PTR [rbp-8], rdi:將 this 指針(在 rdi 中)保存到局部變量中。
  • mov rax, QWORD PTR [rbp-8]:將 this 指針從局部變量中加載到 rax 中。
  • mov rdi, rax:將 this 指針(現在在 rax 中)移動到 rdi 中,以便調用基類構造函數時使用。
  • call A::A() [base object constructor]:調用基類 A 的構造函數。此時,this 指針指向 B 對象,但調用的是 A 的構造函數,因此它會正確初始化 A 的部分。
  • mov rax, QWORD PTR [rbp-8]:再次將 this 指針從局部變量中加載到 rax 中。
  • mov DWORD PTR [rax+4], 1:將 1 賦值給 this->a。這里的 [rax+4] 指的是b 位于對象內偏移量 4 的位置。 (因為B繼承A,B所以內存結構上,前四個字節是A.a ,然后才是B.a ,所以是移動到偏移4位置之后在賦值)

?

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

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

相關文章

【FreeRTOS】同步互斥與通信 有缺陷的同步示例

目錄 1 同步互斥與通信1.1 同步互斥與通信概述1.2 同步與互斥的概念1.3 同步的例子:有缺陷1.4 freertos.c源碼3. 互斥的例子:有缺陷4. 通信的例子:有缺陷5. FreeRTOS的解決方案 1 同步互斥與通信 1.1 同步互斥與通信概述 參考《FreeRTOS入門…

搞錢四步:干活、出名、破圈、整合

搞錢這事兒,說起來有四步:干活、出名、破圈、整合。 咱們現在這個時代,誰要是能把自尊心放一邊,勇敢站到舞臺上展示才華,變現那是分鐘的事兒。 只要你敢承認自己想要財富,并且不停地使用正確的方法論&…

python語句前面有一個$是什么意思

“$”是匯編語言中的一個預定義符號,等價于當前正匯編到的段的當前偏移值。例如:指令“jmp $3”中的“$”表示當前這條指令在代碼段中的偏移量。 代表當前指令的地址,如: data segment str1 db a,b,c,d leng equ $-str 就是當前地…

JVM專題之性能優化

運行時優化 方法內聯 > 方法內聯,是指 **JVM在運行時將調用次數達到一定閾值的方法調用替換為方法體本身** ,從而消除調用成本,并為接下來進一步的代碼性能優化提供基礎,是JVM的一個重要優化手段之一。 > > **注:** > > * **C++的inline屬于編譯后內聯,…

數據庫實訓復習(1)

目錄 一、關于表結構的相關操作(與表中字段的數據操作有區別) (1)往已有的表中添加字段 (2)修改表中已有字段的數據類型 (3)修改已有的表中的字段名和字段類型 (4&a…

TopK問題與堆排序

目錄 TopK問題: 定義: 應用場景: 搜索引擎: 推薦系統: 數據分析: 數據挖掘: TopK問題初階:(數據量較小情況) TopK問題進階:(…

知名品牌因商標痛失市場:114家直營店山寨店7000多家!

奶茶知名品牌“鹿角巷”當年紅遍大江南北,是最早的新茶飲品牌,但是當年商標注冊存在問題,被同行奶茶品牌搶占了先機,發聲明“對大陸商標注冊細則不詳,在商標注冊過程中讓假店鉆了法律空檔”,最夸張的時候全…

qml required property

目錄 前言 示例代碼 創建一個自定義組件(MyComponent.qml) 使用自定義組件(main.qml) 解釋 運行效果 運行時錯誤示例 前言 在 QML 中,你可以使用 required 關鍵字來聲明一個屬性是必需的。這意味著在創建該對象…

如何用Python向PPT中批量插入圖片

辦公自動化辦公中,Python最大的優勢是可以批量操作,省去了用戶粘貼、復制、插入等繁瑣的操作。經常做PPT的朋友都知道,把圖片插入到PPT當中的固定位置是一個非常繁瑣的操作,往往調整圖片時耗費大量的時間和精力。如何能省時省力插…

【數據結構】使用C語言 從零實現一個棧的數據結構

棧 什么是棧?棧是一種特殊的線性表,它只能在在表尾進行插入和刪除操作。 棧的底部稱為棧底,頂部稱為棧頂,所有的操作只能在棧頂進行,也就是說,被壓在下方的元素,只能等待其上方的元素出棧之后…

LeetCode-簡單-回文數

給你一個整數 x ,如果 x 是一個回文整數,返回 true ;否則,返回 false 。 回文數 是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數。 例如,121 是回文,…

windows啟動Docker閃退Docker desktop stopped

Windows啟動Docker閃退-Docker desktop stopped 電腦上很早就安裝有Docker了,但是有一段時間都沒有啟動了,今天想啟動啟動不起來了,打開沒幾秒就閃退,記錄一下解決方案。僅供參考 首先,參照其他解決方案,本…

Ubuntu20安裝mysql方法,適用于wsl

itopen組織1、提供OpenHarmony優雅實用的小工具2、手把手適配riscv qemu linux的三方庫移植3、未來計劃riscv qemu ohos的三方庫移植 小程序開發4、一切擁抱開源,擁抱國產化 一、Ubunt20安裝mysql 適用于wsl中安裝mysql sudo apt update# 查看可使用的安裝包…

【刷題匯總--游游的you、腐爛的蘋果、孩子們的游戲(圓圈中最后剩下的數)】

C日常刷題積累 今日刷題匯總 - day0051、游游的you1.1、題目1.2、思路1.3、程序實現 - 蠻力法1.4、程序實現 - 貪心(優化) 2、腐爛的蘋果2.1、題目2.2、思路2.3、程序實現 - bfs 3、孩子們的游戲(圓圈中最后剩下的數)3.1、題目3.2、思路3.3、程序實現 -- 環形鏈表3.4、程序實現…

2個方法教你輕松移除pdf文件編輯限制

PDF是一種常見的辦公文檔格式,常用于文件共享和保護。然而,有時候我們需要編輯PDF文件中的內容,但受到了編輯限制。本文將介紹一些有效的方法,幫助您解除PDF的編輯限制,輕松進行編輯和修改。 一、通過密碼取消PDF“限制…

雷電模擬器報錯remount of the / superblock failed: Permission denied remount failed

報錯截圖 解決方法 打開設置 設置配置system.vmdk可寫入 解決

Transformer和Mamba強強結合!最新混合架構全面開源,推理速度狂飆8倍

最近發現,將Mamba和Transformer模塊混合使用,效果會比單獨使用好很多,這是因為該方法結合了Mamba的長序列處理能力和Transformer的建模能力,可以顯著提升計算效率和模型性能。 典型案例如大名鼎鼎的Jamba:Jamba利用Tr…

ELK優化之Elasticsearch

目錄 1.ELK優化 2.優化 ES 索引設置 2.1 優化 fsync 2.2 優化 refresh 2.3 優化 merge 2.4 優化設置 2.5 打開索引 3.優化線程池配置 3.1 優化的方案 4.鎖定內存,不讓 JVM 使用 Swap 5.減少分片數、副本數 6.ES優化總結 1.ELK優化 ELK優化可以圍繞著 li…

Python統計實戰:時間序列分析之簡單指數平滑和Holt指數平滑

為了解決特定問題而進行的學習是提高效率的最佳途徑。這種方法能夠使我們專注于最相關的知識和技能,從而更快地掌握解決問題所需的能力。 (以下練習題來源于《統計學—基于Python》。請在Q群455547227下載原始數據。) 練習題 下表是某只股票…

二維平面無中心點的聚類算法

問題描述 二維平面上有許多點p(x , y),按照彼此之間的歐式距離進行分為若干個集合。若點p1(x1, y1)與點p(x2, y2)之間距離小于d,則認為二者是鄰居。 算法思路 給數據集的點進行編號,順序遍歷這些點,找出當前點的鄰居,記住已經遍…