右值引用與移動建構函式 移動賦值

2021-08-09 10:57:19 字數 2489 閱讀 1121

有一陣子沒看c++了,翻開c++primer又陌生了一些,想了想引用,於是乎來看了下右值引用。

int a=5;

int &b=a;

這是左值引用,若我們這樣修改:

int a=5;

int &b=a+1;

編譯器會報錯:非常量引用的初始值必須為左值。也就是右邊的a+1是常量,常量給非常量引用賦值就報錯。

我們可以這樣修改就不報錯了:

int a=5;

const

int &b=a+1;

此時我們可以試一試:

int a = 5;

const

int &b = a+1;

a++;

cout

<< b;

發現b的結果為6,也就是a++並沒有影響到b,也就是說b指向的位址並不是a,而是乙個新的位址存放著a+1的值,但是由於b被const修飾,我們無法修改b的值。

c++11新增了右值引用,那什麼是右值引用呢?右值引用用&&表示,右值可以是常量,或者一些表示式以及返回值的函式,如上面的左值引用,需要修改為const才能夠把常量給賦值過來,而右值引用就如下:

int a=5

; int &&b=a+1

;a++;

cout

該**和上面的那串**結果一樣,其中變數b的位址是存放著a+1值的位址,不同點就是我們可以自由的修改b的值,而不像左值引用那樣被const給限制。

那麼問題就來了,右值引用有什麼用呢?我們來看看在類中的使用吧:

class

a count++;

showdata();

cout << "建構函式"

<< endl;

}~a()

a(const a ©)

count++;

showdata();

cout << "拷貝建構函式"

<< endl;

}a(a &©)

a operator+(const a &test)

for (int i = 0; i < test.len; i++)

return temp;

}a operator=(const a &test)

void showdata()

void aprint()

};int a::count = 0;

int main()

結果:

**、結果分析:

首先,數字1、2下面對應的是a與b物件生成,呼叫建構函式,然後到a+b呼叫operator+,然後返回乙個臨時物件temp(呼叫建構函式),然後就到c(temp),此時並不是呼叫拷貝建構函式,而是移動建構函式,然後我們把原來的a+b產生的臨時物件的str成員置成nullptr,於是呼叫了析構函式,析構0000000的位置(因為我們置臨時物件為空了),而我們的c就相當於竊取了temp的內容(改變了物件裡面的str指標),所以最後c的str位址沒變,還是01052598而內容變為temp的。

那麼,這和拷貝構造有什麼區別呢?區別就是,若我們使用拷貝建構函式,我們將會重新生成臨時物件,然後對臨時的資料進行批量的複製,然後又清除,很費力,而使用移動構造我們可以直接讓資料指向臨時資料所指向的資料,而不用進行批量的複製操作。就例如我們上面的**,若不使用移動建構函式,a+b產生的臨時物件讓c呼叫拷貝構造,然後批量複製資料,若資料越大,就越影響計算機效能。

同樣的,我們既然可以這樣修改建構函式為移動建構函式,我們也可以修改operator=,通過判斷是否是自我複製,若不是,則將我們類的指標成員指向另乙個物件的指標成員,省去很多操作,**如下:

a operator=(a &&test) //此時的引數不能為const,因為我們要修改test的成員

若我們要使用移動賦值,我們可以將要讓賦的值不是左值,看起來像右值,然後呼叫移動賦值運算,我們可以使用static_cast<>將物件的型別強制轉換為classtype &&,除此之外,c++11提供了一種方式,通過使用utility標頭檔案,使用std::move()。

如下:

a

a(3, 'x'), b(2, 'o');

//a=static_cast(b);

a=std::move(b);

a.aprint();

b.aprint();

結果:

可以看見物件b的值被置為空,而a的str值為物件b的str值。

右值引用,移動構造,移動賦值

1 目的 右值引用,移動構造和移動賦值是在c 11中引入的,其目的是為了提公升 效率 2 使用場景 類中如果有需要申請動態資源的成員,那麼定義移動建構函式和移動賦值運算子可以避免不必要的拷貝工作,從而提公升 效率。移動構造和移動賦值並不會新開闢資源,而是將源物件的一部分或全部資源移交給了新物件。st...

C 右值引用與移動構造

c 中提供了兩種引用方式。左值引用與右值引用。其中右值引用是c 11的新標準新增的內容。所謂的右值引用就是必須繫結到右值的引用。在介紹之前,先說明一下c 中的左值和右值的規定。實際上,最早在c語言中就有了左值和右值之分。最初的左值即指在賦值號左邊的變數,右值指在賦值號右邊的變數。隨著c語言的發展和c...

C 11 右值引用(2)移動構造和移動賦值函式

先參考上一節 c 11 右值引用 1 本節是右值引用的第乙個用途 減少拷貝,減低開銷,提高效率。c 11的右值引用概念出來後,c 類的預設函式多了兩個,移動構造和移動賦值函式。之前的所有預設函式為 構造 析構 拷貝構造 拷貝賦值 取址 取址const 下面是乙個簡單例子。class mystring...