從匯編的角度揭開C++ this指針的神秘面紗(下)

<接上篇>

我們接著來看一段C++的代碼:

class A
{
public:int func(int j){return j +_i;}
private:int _i;    
};int main()
{A a;a.func(3);return 0;
}

這里定義了一個類A,在main函數中定義了A類的對像a。同時用a調用了成員函數func。我們來看一下main函數的匯編代碼:

        pushq   %rbpmovq    %rsp, %rbpsubq    $16, %rsp         //rsp = rsp - 16leaq    -4(%rbp), %rax    //rax = rpb -4movl    $3, %esi          //esi = 3movq    %rax, %rdi        //rdi = raxcall    A::func(int)movl    $0, %eaxleaveret

在調用A::func之前,賦值了兩個寄存器:rdi和rsi. 由上篇文單可知,這兩個寄存器用于函數調用時,傳遞第1和第2個參數。那么這里我們有疑問:A::func(int)明明只有一個參數,為什么調用時,傳遞了兩個參數呢?另一個參數是什么呢?答案就是:在調用成員函數時,this指針會做為一個隱含的參數傳遞給成員函數,并且是作為第一個參數。那么this指針又代表什么呢,this指針就是指向類對象的一個地址。對應上面匯編代碼即是rbp-4。源代碼a.func(3)相當于func(this, 3)也就是func(&a, 3);?

為了方便理解,我畫出了main函數的棧空間,如下所示:

this指針存儲的是a對象的地址。即rbp-4. 此時a對象里面只有一個int型的成員變量i, 占用4個字節。

接下來,我們分析一下func函數,匯編如下:

A::func(int):pushq   %rbpmovq    %rsp, %rbpmovq    %rdi, -8(%rbp)      //*(rbp-8) = rdimovl    %esi, -12(%rbp)     // *(rbp-12) = esimovq    -8(%rbp), %rax      // rax = *(rbp-8) movl    (%rax), %edx        // edx = *raxmovl    -12(%rbp), %eax     // eax = *(rbp-12)addl    %edx, %eax          // eax += edxpopq    %rbpret

func函數棧空間如下:??

??

func中會先分配棧空間rbp-8, rbp-12來存儲傳遞過來的參數rdi(this)以及esi(3)。 然后根據這些參數來做下一步處理。

總結:

1)this指針的本質即對象的地址。

2)在調用類成員函數時,C++編譯器會將其作為函數的第一個參數,傳遞給成員函數。

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

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

相關文章

Kafka代碼模板

Kafka 服務器&#xff08;Broker&#xff09; 的配置 server.properties # broker.id: 每個 Kafka Broker 的唯一標識符。broker.id 必須在整個 Kafka 集群中唯一。 broker.id0# 配置 Kafka Broker 監聽客戶端請求的地址和端口。這個配置決定了 Kafka 服務將接受來自生產者、…

最大子數組和C++

給你一個整數數組 nums &#xff0c;請你找出一個具有最大和的連續子數組&#xff08;子數組最少包含一個元素&#xff09;&#xff0c;返回其最大和。 子數組是數組中的一個連續部分。 示例 1&#xff1a; 輸入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 輸出&#xff1a;…

centos 7單機安裝ceph并創建rbd塊設備

1. 安裝依賴包 新增阿里云源ceph下載地址 vim /etc/yum.repos.d/ceph.repo [ceph] nameceph baseurlhttp://mirrors.aliyun.com/ceph/rpm-jewel/el7/x86_64/ gpgcheck0 [ceph-noarch] namecephnoarch baseurlhttp://mirrors.aliyun.com/ceph/rpm-jewel/el7/noarch/ gpgcheck…

Jenkins搭建、權限管理、參數化、流水線等詳細教程!

部署Jenkins 一、jenkins 安裝 官網&#xff1a; https://jenkins.io yum 安裝 jenkins *jenkins 依賴 java 環境 #注意2.346之后的版本不再支持jdk8 卸載舊jenkins #查詢以前是否安裝jenkins rpm -qa |grep jenkins #卸載 jenkins yum -y remove jenkins rpm -e jenkins…

百度飛槳(PaddlePaddle)案例分享:基于 PaddleOCR 的圖像文字提取系統

一、案例背景 在實際教學、辦公及政務系統中&#xff0c;紙質材料&#xff08;如手寫作文、表格、試卷等&#xff09;仍廣泛存在。為提升信息處理效率&#xff0c;采用 OCR&#xff08;Optical Character Recognition&#xff09;技術將圖像中的文字提取為可編輯文本已成為剛需…

python操控鼠標

在已知屏幕坐標的情況下&#xff0c;可以通過 Python 的 pyautogui 或 pynput 等庫實現網頁上的鼠標點擊操作。以下是具體步驟和代碼示例&#xff1a; 1. 使用 PyAutoGUI&#xff08;推薦&#xff09; pyautogui 是一個簡單易用的庫&#xff0c;可以直接通過屏幕坐標控制鼠標點…

UV 與 Bun 深度解析

UV 與 Bun 深度解析&#xff1a;現代開發工具的安裝與使用指南 什么是 UV&#xff1f; UV&#xff08;Ultra-Velocity&#xff09;是由 Astral 公司&#xff08;Ruff 的創建者&#xff09;開發的超高速 Python 包管理工具&#xff1a; 用 Rust 編寫&#xff0c;速度極快&…

【算力網絡】多樣化算力感知

一、算力網絡 ? 算力網絡&#xff08;Computing Power Network&#xff09;是我國率先提出的原創性技術理念&#xff0c;其核心是通過高速網絡整合分散的算力資源&#xff08;如云端、邊緣、終端等&#xff09;&#xff0c;實現算力的動態感知、智能調度和一體化服務&#x…

Greenplum/PostgreSQL pg_hba.conf 認證方法詳解

Greenplum/PostgreSQL pg_hba.conf 認證方法詳解 pg_hba.conf 文件中的 METHOD 字段指定了客戶端認證方式&#xff0c;以下是各種認證方法的詳細說明和配置示例。 常用認證方法 1. trust - 無條件允許連接 說明&#xff1a;不需要密碼&#xff0c;完全信任連接 適用場景&am…

分布式數據庫中間件-Sharding-JDBC

前言 學習視頻&#xff1a;深入Sharding-JDBC分庫分表從入門到精通【黑馬程序員】本內容僅用于個人學習筆記&#xff0c;如有侵擾&#xff0c;聯系刪除 1、概述 1.1、分庫分表是什么 小明是一家初創電商平臺的開發人員&#xff0c;他負責賣家模塊的功能開發&#xff0c;其中…

pycharm2020.2版本給項目選擇了虛擬環境解釋器,項目文件都運行正常,為什么terminal文件路徑的前面沒有虛擬解釋器的名稱

解決問題&#xff1a; 1.打開 Anaconda Prompt輸入 conda init cmd.exe 或者 pycharm終端直接 conda init cmd.exe 重啟動 CMD和pycharm&#xff0c;使配置生效。

2025商旅平臺排行:國內主流商旅平臺解析

在數字化轉型加速2025年&#xff0c;企業商旅管理正從“成本中心”向“智能管控樞紐”升級。如何通過技術賦能實現商旅成本精準優化與管理效率躍升&#xff1f;本文聚焦國內五大主流商旅平臺&#xff0c;以“綜合型頭部平臺創新型平臺”雙維度解析&#xff0c;結合數據實證與場…

CNS無線電信號覆蓋分析系統v0.1

#系統終端有的版本號了# 開發一套類EMACS的專業軟件任重道遠&#xff0c;經過慢吞吞的開發&#xff0c;我們已經將目標定位大幅下調了&#xff0c;不再對標EMACS系統了&#xff0c;改為瞄行業老二WRAP軟件了。當然WRAP軟件在電磁信號仿真分析領域也是神一樣的存在&#xff0c;其…

單視頻二維碼生成與列表二維碼生成(完整版)

視頻二維碼有有兩種情況&#xff1a;一種是單個視頻的生成一個二維碼&#xff1b;另一種是一組視頻&#xff08;多個視頻&#xff09;生成一個列表二維碼。用戶按自己的實際需求生成&#xff0c;即可&#xff0c;很方便。 STEP1 注冊帳號 使用視頻二維碼&#xff0c;您需要注…

關于linux:1. Linux 基礎運維

一、Linux 安裝與發行版選擇 關于操作系統種類&#xff1a; 1&#xff09;基于 Linux 內核的操作系統 Ubuntu、Debian、Kali、CentOS、RHEL、Arch、Android、Alpine、OpenWRT 等 特點&#xff1a;開源、穩定、安全、廣泛使用于服務器與開發領域 2&#xff09;基于 Windows…

(LeetCode 每日一題) 2016. 增量元素之間的最大差值 (數組)

題目&#xff1a;2016. 增量元素之間的最大差值 思路&#xff1a;維護已遍歷過的最小值&#xff0c;時間復雜度0(n)。 C版本&#xff1a; class Solution { public:int maximumDifference(vector<int>& nums) {int mnnums[0];int ans0;for(int i1;i<nums.size()…

MySQL基礎與常用數據類型淺析

一.MySQL數據類型分類 二.數值類型 2.1int類型 我們使用TINYINT作為例子進行實驗驗證: 越界插入會直接報錯,跟我們當時學習語言的時候不太一樣,語言會進行隱式類型轉換或截斷.一般不會直接報錯.其他的int類型也是同理. 說明: 在MySQL中&#xff0c;整型可以指定是有符號的…

Ubuntu 20.04離線安裝Nvidia-docker

服務器因系統故障重裝&#xff0c;安裝docker容器時發現幾年前的在線安裝步驟不好使了&#xff0c;只好嘗試離線安裝。為了下次不卡殼&#xff0c;記錄一下安裝步驟。 先確定自己的操作系統&#xff0c;并確保已經安裝了nvidia driver。我的操作系統是Ubuntu 20.04。 1. 下載…

6,TCP客戶端

1,創建一個新的項目 2,界面設計

【dify更新問題】如何更新dify且低成本解決git pull 443問題

我的dify部署在mini server上&#xff0c;掛不了TZ&#xff0c;所以采用了如下辦法 更新origin (.git/config) 地址為&#xff1a;https://gitee.com/dify_ai/dify.git 順序執行 &#xff08;https://docs.dify.ai/en/getting-started/install-self-hosted/docker-compose#upg…