移動建構函式

2022-09-03 02:51:08 字數 1242 閱讀 2241

c++11新引入了右值引用和移動語義兩個概念。

c++(包括c)中所有的表示式和變數要麼是左值,要麼是右值。通俗的左值的定義就是非臨時物件,可以在多條語句中使用的物件。右值是指臨時的物件,它們只在當前的語句有效。在c++11之前,右值是不能被引用的。如int &a =1; //無法從「int」轉化為「int&」。 我們最多只能用常量引用來繫結乙個右值。因為規定不允許修改右值。在c++11中,可以引用右值,使用&&實現:int &&a = 1;  //ok.

在理解右值引用之前,先理解臨時物件(臨時變數)的概念。

臨時物件是編譯器在編譯**過程中為了實現某些**可能會產生出一些臨時物件來滿足一些效果。產生臨時變數的地方可能有以下幾種:

規定不允許修改臨時變數,所以在沒有引入移動建構函式的時候,拷貝構造的引數為const &型別,以支援通過臨時物件來構造物件。臨時物件在函式返回後很快就會銷毀,為了能物盡其用而達到節省時間(進行物件拷貝)的效果,考慮將臨時物件納為己有,這樣能節省記憶體開闢和繁瑣的賦值時間。

如:mystring(……):_ptr(mystr._ptr)

mystr._ptr = null;

將_ptr指向的真正的字串的所有權拿過來了。括號裡空出來的引數應該是臨時物件,在c++1.0中,無法判斷什麼時候是臨時物件。為此,c++11引入了乙個新的概念——右值引用(&&)。右值引用專門用於引用右值(臨時物件、匿名物件(即沒有名字的物件))。

所以上述建構函式可改寫為:

mystring(mystring &&mystr):_ptr(mystr._ptr)

myptr._ptr = null;

當傳入臨時變數(右值)時,編譯器會呼叫mystring(mystring &&mystr)版本。在函式中,臨時物件的指標置為null,這很重要,防止臨時物件析構時候銷毀字串,使之成為懸掛指標。

拷貝構造是開闢乙個新空間然後對臨時物件(函式引數)進行深度拷貝,返回該新物件。

移動構造不另外開闢新空間,直接偷走臨時物件的記憶體空間,占為己有。

移動構造的優點:節省了開闢記憶體與賦值的時間。

程式設計師提供移動建構函式(引數為右值引用的建構函式)使得當臨時變數構造新物件時可以提供較好的優化。提供移動建構函式在某些情況下對效能是極大的提供,尤其是對於需要深拷貝的物件來說。當這一類物件配合標準庫的容器的時候(vector、deque),如果提供移動建構函式,將會在容器記憶體重分配時帶來極大效率的優化。

用到臨時物件(右值)的時候就會執行移動語義。除了編譯器建立的臨時物件作為右值外,使用std::move也能得到乙個左值的右值引用。

移動建構函式

移動構造 移動構造是c 11標準中提供的一種新的構造方法。在現實中有很多這樣的例子,我們將錢從乙個賬號轉移到另乙個賬號,將手機 sim卡轉移到另一台手機,將檔案從乙個位置剪下到另乙個位置 移動構造可以減少不必要的複製,帶來效能上的提公升。有些複製構造是必要的,我們確實需要另外乙個副本 而有些複製構造...

剖析 移動建構函式

移動建構函式應用的場景?答 有時候我們會遇到這樣一種情況,我們用物件a初始化物件b,後物件a我們就不在使用了,但是物件a的空間還在呀 在析構之前 既然拷貝建構函式,實際上就是把a物件的內容複製乙份到b中,那麼為什麼我們不能直接使用a的空間呢?這樣就避免了新的空間的分配,大大降低了構造的成本。這就是移...

拷貝建構函式和移動建構函式解析

by gongzhihui 2017.12.5 拷貝構造函式呼叫時機 1.物件作為函式引數 2.物件作為函式返回值 3.用乙個物件初始化另乙個物件 t t1 t t2 ti t t3 t1 此處的 不是賦值運算子 拷貝賦值運算子 t t1 t t2 t1 t2 除了 類名 物件 物件 外的 應該都是...