【C++底層剖析】++a vs a++:到底誰是左值,誰是右值?

????????在 C++ 編程中,我們經常使用 ++aa++ 來實現自增操作。乍一看它們只是“先加還是后加”的語法糖,但你真的理解它們的底層機制返回值類型左值右值屬性嗎?

1. ++aa++ 的基礎區別

表達式名稱語義返回值類型左值 / 右值
++a前置自增先將 a 加 1,再返回引用(本體)? 左值
a++后置自增先返回 a 原值,再加 1值(副本)? 右值

2. 什么是左值?什么是右值?

  • 左值(lvalue):表達式擁有持久地址,可以被賦值或取引用。

  • 右值(rvalue):臨時值,不能取地址,也不能作為賦值目標。

前置 ++a 是左值

int a = 10;
++a = 20;     // ? 合法,++a 是左值
int* p = &++a; // ? 合法,可以取地址

后置 a++ 是右值

int a = 10;
a++ = 20;     // ? 錯誤,右值不能賦值
int* p = &a++; // ? 錯誤,不能取右值地址

3. 如果我們重載 ++ 運算符呢?

class Counter {
public:int val;// 前置 ++Counter& operator++() {++val;return *this;  // 返回本體(左值)}// 后置 ++(注意 int 是啞元區分前后)Counter operator++(int) {Counter temp = *this;val++;return temp;   // 返回臨時對象(右值)}
};

測試代碼:

Counter c;
++c = Counter();  // ? 合法
c++ = Counter();  // ? 編譯錯誤

4. 本質原理:編譯器背后做了什么??

????????在 C++ 中,運算符重載允許開發者為類自定義 ++ 操作。編譯器通過你寫的函數簽名自動判斷調用的是前置還是后置:

形式實質調用函數原型說明
++aT& operator++()前置自增:返回引用(左值)
a++T operator++(int)后置自增:返回副本(右值)

????????注:后置 ++ 的函數參數列表中有一個 占位參數 int,它只是用來占位以便區分前置和后置版本,在函數體內不使用。?

自定義前置 ++

class Counter {
public:int val;Counter(int v) : val(v) {}Counter& operator++() { // 前置++++val;return *this;}
};
  • 返回引用(自身)是為了效率與連續操作支持:++++a;

  • 無副本,操作直接作用在當前對象上。


自定義后置 ++

class Counter {
public:int val;Counter(int v) : val(v) {}Counter operator++(int) { // 后置++Counter temp = *this; // 保存舊值val++;                // 再加一return temp;          // 返回舊副本}
};
  • 返回值是對象副本;

  • 適用于int a = b++;這種“先用后改”的語義;

  • 編譯器根據函數簽名自動選擇合適版本。??

5. 常見面試陷阱

題目:下面代碼是否正確?

int a = 3;
(++a) += 5;

?? 正確!因為 ++a 是左值,可以賦值。

int a = 3;
(a++) += 5;

? 錯誤!a++ 是右值,不能賦值。


6. 附:如何判斷左值右值?

????????可用以下方法判斷:

int a = 1;
decltype(++a) x1 = a;  // int&
decltype(a++) x2 = a;  // int

????????也可以直接測試是否能取地址:

int* p = &++a;  // ?
int* q = &a++;  // ?

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

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

相關文章

【世紀龍科技】汽車故障診斷與排除仿真教學軟件讓課堂更高效安全

隨著汽車產業向智能化、電動化快速轉型,職業院校汽修專業的教學模式正面臨全新挑戰。傳統實車實訓存在成本高、風險大、場景單一等問題,而行業對人才的要求卻越來越高——既需要扎實的理論基礎,又必須具備熟練的故障診斷能力。如何在保證安全…

網絡基礎9:按流負載均衡實驗(等價路由)

實驗eNS拓撲圖:1. 網絡拓撲與 IP 配置AR5:GE0/0/0: 192.168.1.1/24(連接 AR6)GE0/0/1: 192.168.3.1/24(連接 AR8)Loopback0: 1.1.1.1/32(源地址)AR6:GE0/0/0: 192.168.1.…

4G模塊 A7680發送中文短信到手機

命令說明 基礎AT指令 ATi顯示產品的標志信息 ATCIMI查詢IMSI ATCICCID從SIM卡讀取ICCID ATCGSN查詢產品序列號 ATCPIN查詢卡狀態 ATCSQ查詢信號強度 ATCGATT查詢當前PS域狀態 ATCREG查詢GPRS注冊狀態 ATCEREG查詢4G注冊狀態 ATCGPADDR查詢PDP地址 ATCMGF選擇短信格式 ATCMGS發…

深度學習-線性神經網絡

文章目錄線性回歸基本概念隨機梯度下降矢量化加速正態分布和平方損失極大似然估計線性回歸實現從0開始**torch.no_grad()的兩種用途****為什么需要 l.sum().backward()?**調用現成庫softmax回歸圖像數據集從0開始實現softmax利用框架API實現課程學習自李牧老師B站的…

【王樹森推薦系統】推薦系統漲指標的方法04:多樣性

漲指標的方法有哪些? 改進召回模型,添加新的召回模型改進粗排和精排模型提升召回,粗排,精排的多樣性特殊對待新用戶嗎,低活用戶等特殊人群利用關注,轉發,評論這三種交互行為 排序的多樣性 精排多…

1. Spring AI概述

一、前言 Spring AI 是由 Spring 團隊推出的開源項目,旨在為 Java 開發者提供簡潔、一致的 Spring 風格開發體驗,用于構建基于生成式人工智能(GenAI)和大型語言模型(LLM)的應用程序。它通過標準化抽象層簡…

[每日隨題10] DP - 重鏈剖分 - 狀壓DP

整體概述 難度:1600 →\rightarrow→ 2200 →\rightarrow→ 2600 P6005 [USACO20JAN] Time is Mooney G 標簽:DP 前置知識:鏈式前向星 難度:綠 1600 題目描述: 輸入格式: 輸出格式: 樣例輸…

【Ubuntu22.04】repo安裝方法

背景 repo是Google開發的用于基于git管理Android版本庫的一個工具,管理多個Git倉庫的工具,它可以幫助您在一個代碼庫中管理多個Git倉庫的代碼。其在鴻蒙操作系統中大量使用。下面我們就介紹repo在wsl中的安裝部署。 安裝方法 使用中國科技大學資源 腳本i…

Vue3的definePros和defineEmits

在 Vue 3 中,defineProps 和 defineEmits 是組合式 API 中用于定義組件的 props 和 事件 的方法,提供了一種更簡潔和明確的方式來管理組件的輸入和輸出。它們屬于 Composition API 的一部分,在 Vue 2 中通常使用 props 和 $emit 來實現。1. d…

【華為機試】122. 買賣股票的最佳時機 II

文章目錄122. 買賣股票的最佳時機 II描述示例 1示例 2示例 3提示解題思路核心觀察關鍵洞察算法實現方法1:貪心算法(推薦)方法2:動態規劃方法3:動態規劃(空間優化)方法4:波峰波谷法算…

Spring MVC @RequestParam注解全解析

RequestParam 注解詳解 RequestParam 是 Spring MVC 中最常用的注解之一,用于從 HTTP 請求中提取查詢參數(Query String)或表單數據。它主要處理 application/x-www-form-urlencoded 類型的請求(如 GET 請求或 POST 表單提交&…

從零掌握XML與DTD實體:原理、XXE漏洞攻防

本文僅用于技術研究,禁止用于非法用途。 Author:枷鎖 文章目錄一、XML基礎1. 什么是XML?2. XML語法規則3. 數據類型二、DTD1. 認識DTD2. 聲明DTD3. DTD實體4. 如何防御XXE攻擊?5. 總結一、XML基礎 1. 什么是XML? XML &#xff1…

.NET 8 Release Candidate 1 (RC1)現已發布,包括許多針對ASP.NET Core的重要改進!

.NET 8 Release Candidate 1 (RC1)發布:ASP.NET Core重大改進來襲! 近日,.NET 8 Release Candidate 1 (RC1)正式發布,這是在今年晚些時候計劃發布的最終 .NET 8 版本之前的兩個候選版本中的第一個。此版本包含了大部分計劃中的功…

Jenkins pipeline 部署docker通用模板

Jenkinsfile: Docker的NETWORK_NAME不要使用bridge默認網絡,要使用自定義的網絡如test默認 bridge 網絡:容器間不能用名字互相訪問,只能用 IP。自定義網絡:容器間可以用名字互相訪問,Docker 自動做了 DNS 解析。pipeli…

【每日算法】專題十五_BFS 解決 FloodFill 算法

1. 算法思想 Flood Fill 問題的核心需求 給定一個二維網格(如像素矩陣)、一個起始坐標 (x, y) 和目標顏色 newColor,要求: 將起始點 (x, y) 的顏色替換為 newColor。遞歸地將所有與起始點相鄰(上下左右) …

ESLint 完整功能介紹和完整使用示例演示

以下是ESLint的完整功能介紹和完整使用示例演示: ESLint 完整功能介紹 一、核心功能靜態代碼分析: 通過解析JavaScript/TypeScript代碼為抽象語法樹(AST),識別語法錯誤、潛在問題(如未定義變量、未使用變量…

解決問題七大步驟

發現問題后尋找解決方案的流程可以細化為 7個核心步驟,每個步驟包含具體措施、信息源和關鍵技巧,形成“從自查到驗證、從獨立解決到尋求幫助”的完整閉環。以下是完善后的流程: 一、明確問題與初步自查(前提:減少無效搜…

思維鏈(CoT)技術全景:原理、實現與前沿應用深度解析

一、核心概念與原理 定義與起源 CoT 是一種引導大語言模型(LLM)顯式生成中間推理步驟的技術,通過模擬人類逐步解決問題的過程,提升復雜任務(如數學證明、多步邏輯推理)的準確性。該概念由 Google Brain 團…

實驗-華為綜合

華為綜合實驗 一 實驗拓撲二 實驗配置交換機2 vlan batch 10 20 int e0/0/2 port link-type access port default vlan 10 int e0/0/1 port link-type access port default vlan 20 int e0/0/3 port link-type trunk port trunk allow-pass vlan alltelnet交換機3 鏈路類型配置…

Matlab打開慢、加載慢的解決辦法

安裝完畢后直接打開會非常慢,而且打開了之后還得加載很久才能運行 解決辦法如下: 1.找到路徑“D:\Program Files\Polyspace\R2020a\licenses”(我是把matlab安裝在D盤了,如果是其他盤修改路徑即可),該路徑記…