C 11右值 右值引用以及move語義

2021-10-21 02:57:01 字數 3043 閱讀 6507

1、字面常量(「1」,「3,2」等)

2、臨時物件(返回非引用型別的函式,算術、關係、位以及後置遞增/遞減原算符)

注意:左值引用的函式,賦值、下標、解引用和前置遞增/遞減運算子返回都為左值

3、無名物件

4、一般函式的返回值也為右值

class

myclass

;myclass()

;//右值

1、右值引用只能繫結到臨時物件

2、右值引用所引用的的物件將要被銷毀

3、該物件沒有其他使用者

4、右值引用可以自由接管所引用的物件資源

5、右值可以繫結到乙個const 的左值引用,不能繫結到非常量左值引用

int a0 =4;

int&a1 =1;

//非法

int&a2 = a0 *1;

//非法

const

int&a3 =1;

//合法

int&&a4 =1;

//合法

int&&a4 = a0 ;

//非法

6、通過 std::move 顯式地將乙個左值轉換為右值(意味著承諾不再使用該左值)

std::string str1

("char");

std::string str2

(std::

move

(str1));

std::cout << str2 << std::endl;

//輸出"char"

std::cout << str1 << std::endl;

//str1物件無內含字元,無輸出

std::move函式原始碼

// function template move

template

<

class

_ty>

_nodiscard constexpr remove_reference_t<_ty>

&&move

(_ty&& _arg)

noexcept

1、函式傳左值引用時,如傳參為不可取位址物件(未發生隱式型別轉換建立臨時物件);傳值的方式為傳入臨時物件時,會呼叫拷貝構造則會降級了效率,那麼右值引用的過載模板則可做到兩者兼具。

2、移動拷貝構造、移動拷貝賦值

class

thread

thread&

operator

=(thread&& _other)

noexcept

void

swap

(thread& _other)

noexcept

//......

};

說明:

#

define

_thr_set_null

(thr)

(thr._hnd =

nullptr

, thr._id =0)

class

thread

//......

};

move語義原理圖

std::swap函式原始碼

template

<

class

_ty,

class

>

inline

void

swap

(_ty& _left, _ty& _right)

_noexcept_cond

(is_nothrow_move_constructible_v<_ty>

&& is_nothrow_move_assignable_v<_ty>

)

1、move語義的swap遷移當乙個類a為has a類b模型時(尤其是在a無資料成員,所有對外方法實現均由類b實現),應該為其定製實現swap成員函式,只需要交換被a::類b*的指向就好,而無需發生構造或拷貝構造,實現基本和std::swap一致。

void

swap

(a& _other)

noexcept

2、拷貝構造和拷貝賦值要先檢測自我賦值拷貝賦值函式要檢測自我賦值,不然會delete自己,後面又會訪問自己。

basic_string&

operator=(

const basic_string& _right)

return(*

this);

}

std::forward函式原始碼

// function template forward

template

<

class

_ty>

_nodiscard constexpr _ty&&

forward

(remove_reference_t<_ty>

& _arg)

noexcept

template

<

class

_ty>

_nodiscard constexpr _ty&&

forward

(remove_reference_t<_ty>

&& _arg)

noexcept

其利用的是

1:classa& &、classa& &&、classa&& &均可折疊常classa&

2:classa&& &&可折疊成classa&&

總結:1:消除兩個物件交換時不必要的物件拷貝,節省運算儲存資源,提高效率

2:能夠更簡潔明確定義泛型函式

C 11 右值引用以及std move

int和int 是什麼?都是型別。int是整數型別,int 則是整數引用型別。相同int 也是乙個型別。兩個引號 是c 11提出的乙個新的引用型別。記住,這是乙個新的型別。默念 10次吧。假設你記住這個新型別,那麼非常多疑問都能迎刃而解。而且對 effective modern c 說到的void ...

C 11 右值引用與move語義

1.右值引用 1.1 右值 右值就是指在下乙個分號後 更準確的說是在包含右值的完整表示式的最後 銷毀的臨時物件。對於c 11,編譯器會依據引數是左值還是右值在複製建構函式和move建構函式間進行選擇。怎樣區分呢?the distinguishing criterion is if it has a ...

c 11 右值引用

右值引用 是一種復合型別,跟c 的傳統引用很類似。為更準確地區分兩種型別,我們把傳統的c 引用稱為 左值引用 而使用 引用 這一術語時,我們的意思同時包含兩種引用 左值引用和右值引用。右值引用的行為跟左值引用類似,不同之處在於 右值引用可以繫結到臨時量 右值 而 非const的 左值引用卻不能繫結到...