左值引用和右值引用

在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()
{
int num1(5);
int num2(10);
int *pnum(&num1);//將num1的地址傳遞給pnum
int * &rnum = pnum;//rnum是pnum的別名
rnum = &num2;//rnumhe pnum指向同一片內存  改變了rnum就相當於改變了pnum
cout << *pnum << endl;


system("pause");

}


void main()
{
int num1(5);
int num2(10);

int * &rnum = &num1;//這是不允許的  無法從“int *”轉換爲“int *&”

system("pause");
}

從以上兩個例子可以看出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;  # 常量左值引用綁定到右值,編程通過
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

右值值引用通常不能綁定到任何的左值,要想綁定一個左值到右值引用,通常需要std::move()將左值強制轉換爲右值,例如:

int a;
int &&r1 = c;             # 編譯失敗
int &&r2 = std::move(a);  # 編譯通過
  • 1
  • 2
  • 3

右值引用的方法就是int * &&rnum = &num1;  。

下面來說一下爲什麼要右值引用,右值引用在你需要使用寄存器中的值的時候可以進行右值引用。寄存器的刷新速度很快,沒有右值引用的話就需要將寄存器中的值拷貝到內存中,在進行使用,這是很浪費時間的。

int getdata(int &&num)
{
cout << num;
num += 10;
return num;
}


void main()
{
int a = 5;
cout << getdata(a + 1) << endl;
}

如上int getdata(int &&num)就是對右值進行引用。 getdata(a + 1) 中a+1是右值在寄存器中,我們是不可以直接對他進行操作的,如果要操作得將其拷貝到內存中,如果是一個非常大的數據這種拷貝就會很佔用內存,如果直接用右值引用就可以直接對其進行操作。從而節約內存。



將右值轉化爲左值  直接新建變量然後賦值就可以了

int b=a+1;將a+1這個右值轉變爲左值了

move(a)將a這個左值轉變爲了右值


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章