close

結果在面完趨勢跟TomTom之後

我終於發現了一件事情

 

我真的廢到笑...

不過就通過個線上測驗而已,面試被問幾個問題就直接趴到地上了

空有邏輯會解題而已,基本功根本不行啊=ˇ=

 

特別是對於C++呢

因為之前工作上用的基本上就是C++98,C++11之後的版本基本不太熟悉

所以最近針對一下C++11的一些特性來做點功課吧

這篇主要是參考底下這幾篇:

http://www.cnblogs.com/tingshuo/archive/2013/01/21/2870035.html

https://en.cppreference.com/w/cpp/utility/move

https://www.zhihu.com/question/286330926

 

C++11中有所謂左值跟右值的概念

比如說底下這行code:

int x = 0;

裡面的x就是左值,0就是右值

那左值跟右值怎麼分呢

最簡單的區分方法就是... 左值是可以被取址的,右值不行

 

簡介完這概念之後,接下來看一下跟這個概念有關的一些東西

首先是左值引用和右值引用的概念

左值引用就是一般常看到的reference,比如說:

int x = 0;

int &y = x;

這時y就是一個左值引用,代表的是x本身

如果去對y賦值,x的值也會改變,有點像C裡面指標的概念

 

右值引用就是一個相對抽象的概念,表示大概會是這樣:

int x = 0;

int &&y = x;

上面的&&y就是一個右值引用,但注意上面那個用法是錯的

正確的方式應該是int &&y = std::move(x);

 

右值引用有點像是把右值給keep住的概念,之後如果有要把keep住的值交給其他左值,這個右值就會原地消失

至於為什麼要有這個東西呢

在C++11之前的版本裡面,要將一個變數賦值給另一個變數的時候,比如說:

int x(0);

int y(x);

假設x和y都是已經存在的變數,在y(x)這個操作中,會經過幾個過程

1. 呼叫constructor,建一個和x一樣的tmp出來

2. 呼叫copy assignment,將tmp的值copy給y

3. 賦值結束,tmp原地解構

這時候可以發現一件事情,就是tmp這個東西其實理論上是不需要的

直接把y裡面的值複製到x就結束了,tmp是多餘的東西

如果tmp的type是一個特殊的type,裡面的資料量龐大,那麼這個操作就會顯得沒效率

(先說結論,有些編譯器會幫忙優化這個情況,不會做複製的動作)

 

所以右值引用這個概念就出現了,如果y(x)裡面的x是右值,上面的操作就會少掉copy那一步

直接把x的內容交給y,或是說把x內部的資源直接讓y接手(讓y的指標指向x的位址),然後x直接指向nullptr

這樣就不需要tmp這個東西了

 

所以在新的概念中,物件的建構子就多了一種,叫做move constructor

大概是長這樣:

A (A&& that) {   // A&& 表示that是一個A型態的右值參考

    A.data = that.data;

    that.data = nullptr;

}

 

具體怎麼使用呢,就是靠move()這個函數,他可以把傳進去的參數轉換成右值

所以不要被move這個名字騙了,他只做了一個轉換的動作

實際上他沒有移動任何東西,移動東西的都是operator

 

比如說底下這樣:

string str("test");

string t(move(str));

cout << str;

上面的例子裡不會輸出任何東西,move(str)表示把str轉成右值

因為傳入的是右值,所以在建構t的時候會去呼叫string的move constructor

而move constructor的行為就像前面A的行為那樣,因此str就會指向nullptr了

 

但如果是底下這樣:

string str("test");

string&& r = move(str);

string t(r);

cout << str;

 

這樣是會印出東西來的,這是為什麼呢

因為在string&& r = move(str);這一行裡,其實只是定義了一個右值引用r指向str而已

在這種表達式中右值引用還是被當作左值,所以其實r還是一個左值

所以strint t(r)其實呼叫的只是一般的constructor,自然str也不會消失

 

但如果是底下這樣:

string t(move(r));

這樣str就會直接不見,因為會去呼叫move constructor來建t

 

...是不是有點複雜

我覺得C++11之後的版本大量用到這個概念,之後有機會再來研究吧

大概的用法就是上面那樣,很多STL的東西都有套用這個概念進去,改良了很多效能方面的問題

使用得當的話對於效能上還是很有幫助的

 

好吧,那今天就這樣了

我看了看也有點昏頭XD

不過至少是有點概念了,下篇再見~

arrow
arrow
    全站熱搜

    頁頁頁六滴 發表在 痞客邦 留言(0) 人氣()