在c++11中可以取位址的、有名字的就是左值,反之,不能取位址的、沒有名字的就是右值(將亡值或純右值)。舉個例子,int a = b+c, a 就是左值,其有變數名為a,通過&a可以獲取該變數的位址;表示式b+c、函式int func()的返回值是右值,在其被賦值給某一變數前,我們不能通過變數名找到它,&(b+c)這樣的操作則不會通過編譯。
左值一定在記憶體中,右值有可能在記憶體中也有可能在暫存器中
int a=5;
int b=a; //此時a在記憶體中
int a=5;
int b=a+1; //此時a+1在暫存器中
int *p=&a; //此時&a在暫存器中
引用:就是取別名 ,引用不可以重定義
void main()
void main()
從以上兩個例子可以看出int *pnum(&num1); int * &rnum = pnum;通過乙個指標在進行取別名是可以的,因為此時指標在記憶體中,而直接int * &rnum = &num1;取別名是不行的,&num1在暫存器中。在記憶體中的值是可以直接取別名的也就是引用。但是在暫存器中的值在不可以直接被引用的。其實這就是所謂的左值引用和右值引用。
在c++11中可以取位址的、有名字的就是左值,反之,不能取位址的、沒有名字的就是右值(將亡值或純右值)。
在記憶體中的變數才是可以取位址的,而在暫存器中的變數是不可以取位址的。對於乙個不能取位址的表示式或者值是無法直接引用的。所以int * &rnum = &num1;編譯不通過。
講了以上那麼多,左值引用就是對乙個左值進行引用的型別。右值引用就是對乙個右值進行引用的型別。右值引用和左值引用都是屬於引用型別。無論是宣告乙個左值引用還是右值引用,都必須立即進行初始化。而其原因可以理解為是引用型別本身自己並不擁有所繫結物件的記憶體,只是該物件的乙個別名。左值引用是具名變數值的別名,而右值引用則是不具名(匿名)變數的別名。
int &a = 2; // 左值引用繫結到右值,編譯失敗
int b = 2; // 非常量左值
const int &c = b; // 常量左值引用繫結到非常量左值,編譯通過
const int d = 2; // 常量左值
const int &e = c; // 常量左值引用繫結到常量左值,編譯通過
const int &b =2; // 常量左值引用繫結到右值,程式設計通過
右值值引用通常不能繫結到任何的左值,要想繫結乙個左值到右值引用,通常需要std::move()將左值強制轉換為右值,例如:
int a;
int &&r1 = c; // 編譯失敗
int &&r2 = std::move(a); // 編譯通過
右值引用的方法就是int * &&rnum = &num1; 。
下面來說一下為什麼要右值引用,右值引用在你需要使用暫存器中的值的時候可以進行右值引用。暫存器的重新整理速度很快,沒有右值引用的話就需要將暫存器中的值拷貝到記憶體中,再進行使用,這是很浪費時間的。
int getdata(int &&num)
void main()
如上int getdata(int &&num)就是對右值進行引用。 getdata(a + 1) 中a+1是右值在暫存器中,我們是不可以直接對他進行操作的,如果要操作得將其拷貝到記憶體中,如果是乙個非常大的資料這種拷貝就會很占用記憶體,如果直接用右值引用就可以直接對其進行操作。從而節約記憶體。
將右值轉化為左值 直接新建變數然後賦值就可以了
int b=a+1;將a+1這個右值轉變為左值了
move(a)將a這個左值轉變為了右值
左值和右值,左值引用和右值引用
左值 lvalue 這一術語 於c語言,用來指代那些可以用在賦值表示式左側的東西,具名物件 在棧和堆上分配的物件,或者其他物件的成員,總之就是又確定儲存空間的東西。而術語右值 rvalue 也是源自c語言,指的是只能在賦值表示式右側出現的東西,如字面值和臨時物件。只能繫結到左值,不能繫結到右值的引用...
左值 右值 左值引用 右值引用
2015 06 01 15 07 404人閱讀收藏 舉報 c 11 5 一 c 中的左值和右值 誤區 左值位於等號左邊,右值位於等號右邊。c 11中的定義 左值表示式表示的是乙個物件的身份 在記憶體中的位置 而右值表示式表示的是物件的值 內容 左值和右值都是針對表示式而言的,左值是持久的,右值是短暫...
左值 左值引用 右值 右值引用
1 左值和右值的概念 左值是可以放在賦值號左邊可以被賦值的值 左值必須要在記憶體中有實體 右值當在賦值號右邊取出值賦給其他變數的值 右值可以在記憶體也可以在cpu暫存器。乙個物件被用作右值時,使用的是它的內容 值 被當作左值時,使用的是它的位址。2 引用 引用是c 語法做的優化,引用的本質還是靠指標...