日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

左值、右值、左值引用、右值引用

發(fā)布時間:2024/4/18 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 左值、右值、左值引用、右值引用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 左值

左值(lvalue,left value),顧名思義就是賦值符號左邊的值,可以取地址。準(zhǔn)確來說,左值是表達(dá)式(不一定是賦值表達(dá)式)后依然存在的持久對象。

可以將左值看作是一個關(guān)聯(lián)了名稱的內(nèi)存位置,允許程序的其他部分來訪問它。在這里,我們將 "名稱" 解釋為任何可用于訪問內(nèi)存位置的表達(dá)式。所以,如果 arr 是一個數(shù)組,那么 arr[1] 和 *(arr+1) 都將被視為相同內(nèi)存位置的“名稱”。

2. 右值

右值(rvalue,right value),右邊的值,是指表達(dá)式結(jié)束后就不再存在的臨時對象,不能取地址

純右值(prvalue,pure rvalue),純粹的右值,要么是純粹的字面量,例如10, true;要么是求值結(jié)果相當(dāng)于字面量或匿名臨時對象,例如1+2。非引用返回的臨時變量、運算表達(dá)式產(chǎn)生的臨時變量、原始字面量、Lambda表達(dá)式都屬于純右值。

小結(jié):相對而言,右值則是一個臨時值,它不能被程序的其他部分訪問。為了說明這些概念,請看以下程序段:

int square(int a){ return a * a;}int main(){ int x = 0; // 1 x = 12; // 2 cout << x << endl; // 3 x = square(5); // 4 cout << x << endl; // 5 return 0;}

在該程序中,x 是一個左值,這是因為 x 代表一個內(nèi)存位置,它可以被程序的其他部分訪問,例如上面注釋的第 2、3、4 和 5 行。

而表達(dá)式 square(5) 卻是一個右值,因為它代表了一個由編譯器創(chuàng)建的臨時內(nèi)存位置,以保存由函數(shù)返回的值。該內(nèi)存位置僅被訪問一次,也就是在第 4 行賦值語句的右側(cè)。在此之后,它就會立即被刪除,再也不能被訪問了。

對于包含右值的內(nèi)存位置來說,其本質(zhì)就是:它雖然沒有名稱,但是可以從程序的其他部分訪問到它。

?

3. 左值引用

左值引用的聲明是通過在某個類型后放置一個符號&來進(jìn)行的。前文代碼中的int & y = x;便是一個左值引用。


需要注意的是,在定義左值引用時,=右邊的要求是一個可修改的左值。因此下面幾種左值引用都是錯誤的:

#include <stdio.h> int main(){ const int x = 5; int y = 1; int z = 1; int & tmp1 = x; // ERROR:x不是一個可修改的左值 int & tmp2 = 5; // ERROR:5是一個右值 int & tmp3 = y + z; // ERROR:y+z是一個右值 return 0;}

左值引用的用途:?

(1) 作為復(fù)雜名稱變量的別名


我們可以寫出類似如下的語句:

auto & whichList = theList[myHash(x, theList.size())];

可以看到,我們用簡短的whichList代替了其原本復(fù)雜的名稱,這能夠簡化我們的代碼書寫。


(2) 用于rangeFor循環(huán)


設(shè)想我們希望通過rangeFor循環(huán)使一個vector對象所有值都增加1,下面的rangeFor循環(huán)是做不到的、

for (auto x : arr) // x僅相當(dāng)于每個元素的拷貝 ++x;

但我們可以通過使用引用達(dá)到這一目的

for (auto & x : arr) ++x;

(3) 避免復(fù)制大的對象


假定有一個findMax函數(shù),它返回一個vector中最大的元素。若給定vector存儲的是某些大的對象時,下述代碼中的x拷貝返回的最大值到x的內(nèi)存中:

auto x = finaMax(vector);

在大型的項目中這顯然會增大程序的開銷,這時我們可以通過引用來減小這類開銷

auto & x = findMax(vector);

類似的,我們在處理函數(shù)返回值的時候也可以使用傳引用返回。但是要注意,當(dāng)返回的是類中私有屬性時,傳回的引用會導(dǎo)致外界能夠?qū)ζ湫薷摹?/p>


(4) 參與函數(shù)中的參數(shù)傳遞


在C和C++的函數(shù)中,addSelf(int x)這類函數(shù)對直接傳入的參數(shù)進(jìn)行修改并不會改變原有參數(shù)的值。而有時我們希望能夠?qū)崿F(xiàn)類似swap(int a, int b)這類能夠修改原參數(shù)的函數(shù)時,我們可以通過1.傳入指針和2.傳入引用實現(xiàn)。
swap函數(shù)的實現(xiàn)是一個很好的例子

#include <stdio.h> void swap_non(int, int); // 直接傳入?yún)?shù) void swap_p(int *, int *); // 傳入指針void swap_r(int &, int &); // 傳入引用 int main(){ int a = 1; int b = 2; printf("直接傳入?yún)?shù)時:\n"); swap_non(a, b); printf("a = %d, b = %d\n", a, b); printf("傳入指針時:\n"); swap_p(&a, &b); printf("a = %d, b = %d\n", a, b); printf("傳入引用時:\n"); swap_r(a, b); printf("a = %d, b = %d\n", a, b); return 0;} void swap_non(int a, int b){ int temp = a; a = b; b = temp;} void swap_p(int * a, int * b){ int temp = *a; *a = *b; *b = temp;} void swap_r(int & a, int & b){ int temp = a; a = b; b = temp;}

4. 右值引用

首先要提出一個新的概念: 將亡值(xvalue,expiring value),是C++11為了引入右值引用而提出的概念(因此在傳統(tǒng) C++中,純右值和右值是同一個概念),也就是即將被銷毀、卻能夠被移動的值

C++11 引入了右值引用的概念,以表示一個本應(yīng)沒有名稱的臨時對象。右值引用的聲明與左值引用類似,但是它使用的是 2 個 & 符號(&&),以下代碼使用了右值引用打印了兩次 5 的平方:

int && rRef = square(5);cout << rRef << endl;cout << rRef << endl;

有意思的是,聲明一個右值引用,給一個臨時內(nèi)存位置分配一個名稱,這使得程序的其他部分訪問該內(nèi)存位置成為了可能,并且可以將這個臨時位置變成一個左值。

右值引用不能約束到左值上,所以,以下代碼將無法編譯:

int x = 0;int && rRefX = x;

再來看以下初始化語句:

int && rRef1 = square(5);

在初始化完成之后,這個包含值 square(5) 的內(nèi)存位置有了一個名稱,即 rRef1,所以 rRef1 本身變成了一個左值。這意味著后面的這個初始化語句將不會編譯:

int && rRef2 = rRef1;

究其原因,就是右側(cè)的 rRef1 不再是一個右值。綜上所述,臨時對象最多可以有一個左值引用指向它。如果函數(shù)有一個臨時對象的左值引用,則可以確認(rèn),程序的其他部分都不能訪問相同的對象。

右值引用會涉及到很多概念比如移動語義,完美轉(zhuǎn)發(fā),會在今后的文章中聊

引用和指針的區(qū)別

我們知道,指針是在內(nèi)存中存放地址的一種變量,cpu能夠直接通過而變量名訪問唯一對應(yīng)的內(nèi)存單元,且每個內(nèi)存單元的地址都是唯一的。
而變量名和引用,都可以看做內(nèi)存的一個標(biāo)簽或是標(biāo)識符,計算機通過是否符合標(biāo)識符判斷是否為目標(biāo)內(nèi)存,而一個內(nèi)存可以有多個標(biāo)識符

?

?

總結(jié)

以上是生活随笔為你收集整理的左值、右值、左值引用、右值引用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。