C++語法系列——引用的左值/右值之分

目錄

 

(1)爲何要區分?

(2)那什麼是左值/右值引用?

(3)左值?右值?

(4)左值/右值,與左值/右值引用有什麼區別?


(1)爲何要區分?

    引用的類型是左值/右值,指明瞭其綁定的對象的狀態是仍有可能被使用,or不再被修改、使用甚至被銷燬。而對象的狀態(左值/右值)又可決定,如何“拷貝”對象所擁有的動態資源——拷貝or接管。這一操作依賴類內的拷貝/移動構造函數以及拷貝/移動賦值運算符。

下面以vector<int>舉例,窺探對象的狀態(左值/右值)對“拷貝”對象這一操作的影響:

#define HUGENUM 1000000000 //10億
int main()
{
    vector<int> A(HUGENUM, 50), B, C; //vector類的對象內擁有動態資源
    clock_t start, end;
    start = clock();
    B = A; // 拷貝資源
    end = clock();
    cout << "time consumed on copy is " << (end - start) / CLK_TCK << endl;
    start = clock();
    C = std::move(A); // 移動(接管)資源
    end = clock();
    cout << "time consumed on move is " << (end - start) / CLK_TCK << endl;
}

運行結果如下:

可見,對於擁有動態資源的對象,其狀態(左值/右值)決定了其被“拷貝”時的具體實現,而當對象擁有大量的動態資源時,這一實現會影響到運行效率。

(2)那什麼是左值/右值引用?

形式上,定義引用時有一個&修飾符的則爲左值引用,有兩個&修飾符的則爲右值引用。左值/右值引用必須綁定對應狀態的對象,如下:

---- 右值引用只能綁定到右值對象上;

---- 非const左值引用只能綁定到左值對象上,而const左值引用對於左值/右值對象均能綁定。(const左值引用無法修改其綁定的對象,這符合右值的設計理念)

(3)左值?右值?

左值可位於賦值號的左側和右側,其值既能被使用也能被修改。而右值只能位於賦值號右側,可使用而不可修改其值。

常見左值包括:定義的對象、引用(不論左值/右值)、賦值/下標/解引用/前置自增自減等運算符返回的值,以及返回類型爲引用類型的函數所返回的值;

常見右值包括:字面值常量、算數/關係/邏輯/位等運算返回的值、後置自增自減運算符返回的值,以及返回類型爲非引用類型的函數所返回的值。

(4)左值/右值,與左值/右值引用有什麼區別?

---- 左值/右值引用本身屬於左值,既能使用也能修改其綁定的對象的值。但我們在使用右值引用時,還是應該遵循右值的設計理念,即假設右值引用綁定的對象不會再被修改、使用,甚至可能立刻被銷燬;

---- 右值引用綁定的既可能是真實的右值如(3)所述,也可能是我們希望是右值但實際並不是的普通對象(利用std::move()轉換)。

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