看了很多篇文章,現在終於搞懂了c++ 中的右值以及std::move
左值和右值最重要的區別就是右值其實是乙個臨時的變數
在c++ 11中,也為右值引用增加了新語法,即&&
比如如下**:
void testfunc(int &i )void testfunc( int &&i )
intmain()
此時輸出為:
right value test func
intright value test func
intreference test func
int
此時有兩行輸出是right value test func int,其他的都是輸出reference test func int
只要注意看這兩行就會發現,在testfunc(1)的時候,我們建立了乙個臨時變數,在testfunc(int())的時候,我們建立了乙個int()的臨時變數,
此時會被編譯器解析為右值,然後匹配到testfuunc(int &&i)裡面
從這上面應該都懂得了什麼是右值,什麼是左值
我們可以把左值轉換為右值,即為std::move
此時在上面的**如果我們呼叫 testfunc( std::move(j) )的話,則會呼叫到testfunc( int &&i)這個函式
那麼這個右值引用和std::move有什麼用呢??
就是減少資源轉移所造成的成本
在c++中,我們最經常接觸的資源就是記憶體了,想象一下,假設乙個string oldstring,裡面new 了1w個位元組,此時我們呼叫了newstring= oldstring的時候,那麼我們將會呼叫string &operator=(const string &other)這個函式
在string &operator=(const string &other)中,我們一般做如下動作:
1.申請1w(或者多個)位元組
2.將這1w個位元組複製到這新開闢的記憶體中
到目前為止都沒什麼問題,但是想象一下,假如我們可以肯定oldstring已經不再使用了怎麼辦??我們還是要多申請這1w個記憶體嗎??為什麼不直接把oldstring的指標直接賦值給newstring呢??反正oldstring已經不用了..
這就是增加了右值語義的原因了,這個時候我們可以定義乙個函式
string &operator=(string &&other)
如上面的偽**,資源將會被移動到新的字串中,因為是移動,不是複製,所以記得將原來的指標什麼的賦值為nullptr
然後我們可以用move將oldstring轉換為右值了
newstring = std::move( oldstring)
此時將會呼叫string &operator=(string &&other),我們就少申請了1w個位元組了,但是原來oldstring的資源也被移動走了,這就是移動語義的真正意義
C 11 右值引用以及std move
int和int 是什麼?都是型別。int是整數型別,int 則是整數引用型別。相同int 也是乙個型別。兩個引號 是c 11提出的乙個新的引用型別。記住,這是乙個新的型別。默念 10次吧。假設你記住這個新型別,那麼非常多疑問都能迎刃而解。而且對 effective modern c 說到的void ...
C 11右值 右值引用以及move語義
1 字面常量 1 3,2 等 2 臨時物件 返回非引用型別的函式,算術 關係 位以及後置遞增 遞減原算符 注意 左值引用的函式,賦值 下標 解引用和前置遞增 遞減運算子返回都為左值 3 無名物件 4 一般函式的返回值也為右值 class myclass myclass 右值 1 右值引用只能繫結到臨...
C 11 中的右值引用
右值引用的功能 首先,我並不介紹什麼是右值引用,而是以乙個例子裡來介紹一下右值引用的功能 include include usingnamespacestd classobj obj constobj other vectorfoo intmain 首先我們編譯一下這個函式,執行結果如下 tianf...