文章目錄
- 11.1左值和右值
- 11.1.1左值和右值概述
- 11.1.2左值和右值的轉換
- 11.1.3左值參考和右值參考
- 11.2移動
- 11.2.1復制和移動
11.1左值和右值
11.1.1左值和右值概述
- C++每個運算式可分為左值和右值(l值和r值),
- 一個運算式不是左值就是右值,
?
- 左值有可標識的記憶體地址并可以長時間存在
- 右值沒有可識別記憶體地址,僅僅存盤暫時結果,
- 左值的名稱來源于歷史上左值運算式,通常出現在賦值運算子的左邊,
- 右值出現在右邊,
- 一個變數的運算式就是一個左值,左值、右值指的是運算式,而不是值,
?
- 賦值陳述句的左運算元必須是一個左值,
- 變數var就是一個左值,
- 它是一個具有可標識的記憶體地址,
- 反過來
- 常量3和運算式(var+1)都不是左值(都是右值),因為它們是運算式的臨時結果,沒有可以標識的記憶體地址(不能用取地址運算子得到它們的地址),
- 僅是計算程序中暫時保存在暫存器的臨時值,給它們賦值沒有意義(也無法給它們賦值)
?
- 函式回傳結果運算式經常是一個右值
- 對函式結果賦值
?
- 不是所有函式的回傳結果都是右值
- 回傳一個全域變數的參考,這個參考就是一個左值,可給它賦值,
- 前面的類(8.1.2節的Point)的下標運算子函式通常有2個實作,其中回傳的是參考(即左值),可以對回傳的non-const參考賦值
- P[1]是一個左值,它是Point類物件的成員變數y的參考,是Point的non-const版本的下標運算子函式Point::operator[]的回傳值
?
?
- 判斷一個運算式是否是左值就是看它是否可以長期存在,即是否有一個地址,
- 取地址運算子&幫助判斷
?
- &a就是一個右值,
- 不能對它再取地址(&&a)了
11.1.2左值和右值的轉換
- 左值可轉換為右值
- &作用于一個左值得到的是一個右值,
- 運算子實際是對右值進行計算的,因為參與運算的值都要放到處理器的臨時暫存器中,
- 運算子作用于左值,實際上會將左值隱式轉換為右值(即移動到臨時暫存器中)

- a+b中左值a和b都會隱式轉換為右值,然后參與運算,運算的結果也是在臨時暫存器中,即也是右值,
?
- 右值不能轉換為左值,
- 并不意味著右值不能產生一個左值,

- p+1是右值,
- 但*(p+1)是一個左值
?
- 左值通常是可以修改的(但不是都如此),而右值是不可以修改的,
- C++11后,右值參考( rvalue references)的概念,使右值也可修改
11.1.3左值參考和右值參考
- 前面的參考變數都是一種左值參考
- 即參考的是一個左值
- C++11引入右值參考
- 參考的也可以是一個右值,
- 和左值參考一樣,右值參考也是一個變數的別名,但它參考的是一個運算式的結果,盡管這個結果在一個臨時記憶體里,
- 系結到右值參考會延長這種瞬態值的生命周期,
- 只要右值參考在作用域內,就不會丟棄右值的記憶體,
?
- 2個&&定義一個右值參考
?
- int&& rtemp{var+3}定義一個右值參考rtemp系結到一個右值運算式var+3的臨時結果
- 在rtemp的作用域中,這個臨時結果始終存在
- 輸出8
?
- 可系結右值參考到一個右值
- 不能系結右值參考到一個左值
- 普通參考不能系結到一個右值,
- const物件的參考可以系結到一個右值
- 右值參考主要用于move移動語意
11.2移動
11.2.1復制和移動
- 對一個類X和該類物件y
- 定義變數X x{y}時調拷貝建構式X(const X &)
- 將y的內容復制到x中去
- 對于X的2個變數x、y,執行x=y時,會調賦值運算子函式,
- 將y的內容復制到x中
?
- 復制是有一定開銷的,物件如果占據記憶體越大,則復制開銷越大,
- 有時應該避免這種不必要的復制
- 執行x=fun()時,將fun()回傳值復制到臨時變數,再將臨時變數賦值給變數x
- 共執行2次復制
- 輸出結果
- 拷貝建構式
- 賦值建構式
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/171215.html
標籤:其他
上一篇:位元幣交易中的簽名
