[ C++ ] | C++11 從左值引用到右值引用

(目錄占位)

1. 前言:

C++ 11 是在 C++ 98 之后又一個變化比較大的標準。為C++增加了很多東西,其中有一部分是有用的,有一部分是我自認為作用不是很大東西。這一章呢?我們就來說說C++11我,我認為對性能優化最有用的一部分 ---- 右值引用

2. 簡單回顧:左值引用

左值?我們現在說說什么是左值?

直接拋結論:能取地址的值或者表達式結果就是左值。左值可以出現在 = 左邊,也可以出現在 = 右邊,不能僅僅以 = 號來區分左右值。

最開始時候的引用,就是左值引用,在C++的語法層面上,引用是給一個變量起一個別名,是不開辟空間的,目的是為了:減少拷貝,提高效率

我們通常在學習的時候與 指針 對照學習。

語法層面(指針對比引用):

引用在定義的時候必須初始化,指針在定義的時候是可以不初始化的。

引用是沒有空引用的,但是指針呢?他是有空指針的,比如C++11之前的NULL和C++11提供的nullptr。

引用是不開辟空間的,但是指針是需要開辟4個字節或者8個字節的空間的。

引用和指針都有一個概念:權限的方法和縮小,首先一說,只有引用和指針有權限的放大和縮小。其他的語法是沒有的,我們在學習的時候,千萬不要自己創造語法...

權限的放大:
#include <iostream>int main()
{const int a = 10;int &b = a; // 權限的放大const int c = 20;int *p = &c; // 權限的放大return 0;
}

變量 a 的權限是 可讀, 但是 變量 b 作為變量 a 的引用,權限卻是可讀可寫。?

變量 c 的權限是 可讀, 但是 變量 p 指向 變量 a,權限卻是可讀可寫。

上面這兩種情況都是編譯器默認不被允許的。?

權限的縮小:
#include <iostream>int main()
{int a = 10;const int &b = a; // 權限的縮小int c = 20;const int *p = &c; // 權限的縮小return 0;
}

變量 a 的權限是 可讀可寫, 但是 變量 b 作為變量 a 的引用,權限是可讀。?

變量 c 的權限是 可讀可寫, 但是 變量 p 指向 變量 c,權限是可讀。

上面的這兩種情況是編譯器默認被允許的。

小結:

權限的放大是不被允許的,但是權限的縮小是被允許的。

權限的放大和縮小都是語法層面的概念,都是被編譯器約束的,我們可以通過強制類型轉換來放大或者縮小權限(但是不推薦,因為有風險),都只是為了“騙”過編譯器。

匯編層面:

引用和指針是一個的,都是開辟可一塊空間,用來保存地址,指針變量就是用來保存指向的對象的地址,引用也是一樣的,開辟一塊空間,用來保存被起別名的對象的地址。

3. 本章主角:右值引用

相對于左值來說,右值就是不能取地址的值,并且右值是不能出現在 = 號的左邊的。

自定義類型的右值常見的兩種形式 : 臨時對象 匿名對象

C++11 對右值又做了細分:純右值(內置類型) 和將亡值(自定義類型),我們的主要研究對象就是:將亡值(自定義類型)

編譯器在進化過程中,將 拷貝構造?+ 構造 優化成 直接構造

比如說在函數棧幀內返回一個比較大的對象的時候,右值引用的價值就極大了。

{

? ? ? ?原來: 跨行的:構造 + 拷貝構造

? ? ? ?現在: 跨行的:構造 + 移動構造

}

減少了一次拷貝,還是很可觀的。

移動構造,移動賦值

有了移動構造之后: 返回時先拷貝構造生成臨時對象,用臨時對象移動構造

如果 “析構函數”,“拷貝構造”,“拷貝賦值” 都沒有實現編譯器就會自動生成 “移動構造”

編譯器生成的移動構造:內置類型去值拷貝,自定義類型去調用它自己的移動構造

為什么?

需要顯式寫析構,說明有資源要釋放,說明需要顯式寫拷貝構造重載

說明要顯式寫移動構造移動賦值

要么都自己寫,要么都編譯器自己生成。

4. 左值引用和右值引用

這個部分我們主要討論一下,左值引用是否能引用右值,右值引用是否能引用左值,就是是否能交叉?

先看右值引用能否引用左值?

但是這樣:const 左值引用 可以給引用右值 是可以的

除了這樣,我們還可以通過強制類型轉換來讓左值引用引用右值,右值引用引用左值。

5. 小結

左值引用和右值引用的目的都是為了:減少拷貝,提高效率。但是他們都是編譯器層面的概念,是可以通過強制類型轉化來轉化的(騙編譯器,不建議)。

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

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

相關文章

基于MCU實現的電機轉速精確控制方案:軟件設計與實現

本文將詳細介紹一篇基于微控制器&#xff08;MCU&#xff09;的電機轉速精確控制的軟件方案。通過采樣PWM信號控制和ADC采樣技術&#xff0c;結合PID閉環控制算法&#xff0c;實現了電機轉速的高效、穩定調節。以下是軟件方案流程圖&#xff0c;下文將對其進行展開講解。 原圖太…

Jmeter觸發腳本備份

JMeter 在以下情況會觸發腳本備份&#xff1a; 手動保存測試計劃時&#xff1a;如果測試計劃有未保存的修改&#xff0c;當用戶手動保存測試計劃&#xff08;腳本&#xff09;時&#xff0c;JMeter 都會自動將當前腳本備份到${JMETER_HOME}/backups文件夾下。 關閉 JMeter 時…

AI人工智能-PyCharm的介紹安裝應用

下載與安裝 創建python項目 項目路徑&#xff1a;C:\Users\miloq\Desktop\python_project 配置環境 提前找到conda配置的python-base路徑 配置conda環境 運行項目 運行結果

Flink內存模型--flink1.19.1

Flink 的 JobManager 和 TaskManager 在內存分配上有不同的職責和結構。以下是兩者的內存分類及詳細說明&#xff1a; 一、JobManager 內存分類 JobManager 主要負責作業調度、協調&#xff08;如 Checkpoint 協調&#xff09;、資源管理等&#xff0c;其內存需求相對較低&…

華為數字化轉型-方法篇

1 方法篇-3-愿景驅動的數字化轉型規劃 1.2 業務戰略是數字化轉型的龍頭 1.3 數字時代&#xff0c;企業需要適時地調整業務戰略 1.3.1 引入數字化商業模式 引入數字化商業模式包括改變與客戶做生意的方式&#xff0c;改變銷售的渠道&#xff0c;基于產業互聯網重新定位與行 業…

常用的排序算法------練習4

1. 題目 2. 思路和題解 這道題是很經典的荷蘭國旗問題&#xff0c;根據題目意思&#xff0c;要對這個數組按照顏色排序&#xff0c;而此時現在的紅、白、藍三個顏色分別對應0&#xff0c;1&#xff0c;2&#xff0c;因此可以想到使用冒泡排序對該數組進行排序。 代碼如下&…

傳統神經網絡、CNN與RNN

在網絡上找了很多關于深度學習的資料&#xff0c;也總結了一點小心得&#xff0c;于是就有了下面這篇文章。這里內容較為簡單&#xff0c;適合初學者查看&#xff0c;所以大佬看到這里就可以走了。 話不多說&#xff0c;上圖 #mermaid-svg-Z3k5YhiQ2o5AnvZE {font-family:&quo…

1371. 貨幣系統-dp背包問題

給定 V種貨幣&#xff08;單位&#xff1a;元&#xff09;&#xff0c;每種貨幣使用的次數不限。 不同種類的貨幣&#xff0c;面值可能是相同的。 現在&#xff0c;要你用這 V種貨幣湊出 N 元錢&#xff0c;請問共有多少種不同的湊法。 輸入格式 第一行包含兩個整數 V 和 N…

python和Java的區別

Python和Java是兩種流行的編程語言&#xff0c;它們之間有一些重要的區別&#xff1a; 語法&#xff1a;Python是一種動態類型的腳本語言&#xff0c;語法簡潔明了&#xff0c;通常使用縮進來表示代碼塊。Java是一種靜態類型的編程語言&#xff0c;語法更為嚴格&#xff0c;需要…

正則化是什么?

正則化&#xff08;Regularization&#xff09;是機器學習中用于防止模型過擬合&#xff08;Overfitting&#xff09;的一種技術&#xff0c;通過在模型訓練過程中引入額外的約束或懲罰項&#xff0c;降低模型的復雜度&#xff0c;從而提高其泛化能力&#xff08;即在未見數據上…

計算機網絡——傳輸層(TCP)

傳輸層 在計算機網絡中&#xff0c;傳輸層是將數據向上向下傳輸的一個重要的層面&#xff0c;其中傳輸層中有兩個協議&#xff0c;TCP&#xff0c;UDP 這兩個協議。 TCP 話不多說&#xff0c;我們直接來看協議報頭。 源/目的端口號&#xff1a;表示數據從哪個進程來&#xff0…

界面控件DevExpress WinForms v25.1 - 人工智能(AI)方面全新升級

DevExpress WinForms擁有180組件和UI庫&#xff0c;能為Windows Forms平臺創建具有影響力的業務解決方案。DevExpress WinForms能完美構建流暢、美觀且易于使用的應用程序&#xff0c;無論是Office風格的界面&#xff0c;還是分析處理大批量的業務數據&#xff0c;它都能輕松勝…

WinFrom真入門(1)——Windows窗體應用概念

窗體的基本結構 用Winform開發的桌面程序&#xff0c;是在Windows操作系統上運行的&#xff0c;這個不用多說。窗體&#xff08;Form&#xff09;的作用?&#xff1a;窗體是用戶交互的容器&#xff0c;承載按鈕、文本框等控件&#xff0c;構成應用程序的界面?。 在Windows操…

scss預處理器對比css的優點以及基本的使用

本文主要在vue中演示&#xff0c;scss的基本使用。安裝命令 npm install sass sass-loader --save-dev 變量 SCSS 支持變量&#xff0c;可將常用的值&#xff08;如顏色、字體大小、間距等&#xff09;定義為變量&#xff0c;方便重復使用和統一修改。 <template><…

Postman 如何高效地轉換時間戳?

在 Postman 中&#xff0c;時間戳的處理對于 API 請求和響應的調試和測試至關重要&#xff0c;正確處理時間戳可以確保數據的準確性和一致性&#xff0c;而 Moment 庫和原生 JS 是兩種常見的處理方式。此外&#xff0c;我們還將介紹 Apifox&#xff0c;它提供了更直觀、更簡便的…

iptables學習記錄

一.四表 filter 表&#xff1a; 主要用于控制數據包的過濾&#xff0c;決定數據包是否允許進出及轉發 。比如設置規則允許特定 IP 訪問服務器的 SSH 端口&#xff08;22 端口&#xff09;&#xff0c;或禁止某些 IP 訪問網站端口&#xff08;80 或 443 端口 &#xff09;。可作…

前端自動創建react項目腳手架

步驟&#xff1a;在終端窗口運行如下命令&#xff1a; npm create vitelatest 也可以指定 vite包 版本&#xff0c; 例如&#xff1a; npm create vite4.1.0 npm執行npm install 很慢 還出現證書問題 執行命令行:npm install -g create-vite npm error code UNABLE_TO_GET_IS…

[從零開始學習JAVA ] 了解線程池

前言&#xff1a; 在Java編程中&#xff0c;線程池是一個強大的工具&#xff0c;它能夠管理和復用線程&#xff0c;提供高效的并發處理能力。通過線程池&#xff0c;我們可以有效地控制并發線程的數量&#xff0c;并降低線程創建和銷毀的開銷。本文將引導你深入了解Java中的線程…

Nginx — Nginx處理Web請求機制解析

一、Nginx請求默認頁面資源 1、配置文件詳解 修改端口號為8080并重啟服務&#xff1a; 二、Nginx進程模型 1、nginx常用命令解析 master進程&#xff1a;主進程&#xff08;只有一個&#xff09; worker進程&#xff1a;工作進程&#xff08;可以有多個&#xff0c;默認只有一…

【C++標準IO庫】字符串流

目錄 一、字符串流概述 1.1 流的概念回顧 1.2 字符串流的定義和作用 二、istringstream 的使用 2.1 基本用法 2.2 常見應用場景 三、ostringstream 的使用 3.1 基本用法 3.2 常見應用場景 四、stringstream 的使用 4.1 基本用法 4.2 常見應用場景 五、字符串流的錯…