国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

詳解 C++ 左值、右值、左值引用以及右值引用

這篇具有很好參考價值的文章主要介紹了詳解 C++ 左值、右值、左值引用以及右值引用。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、左值和右值

1.左值

左值是一個表示數(shù)據(jù)的表達式,比如:變量名、解引用的指針變量。一般地,我們可以獲取它的地址對它賦值,但被 const 修飾后的左值,不能給它賦值,但是仍然可以取它的地址。

總體而言,可以取地址的對象就是左值。

// 以下的a、p、*p、b都是左值
int a = 3;
int* p = &a;
*p;
const int b = 2;

2.右值

右值也是一個表示數(shù)據(jù)的表達式,比如:字面常量、表達式返回值,傳值返回函數(shù)的返回值(是傳值返回,而非傳引用返回),右值不能出現(xiàn)在賦值符號的左邊且不能取地址。

總體而言,不可以取地址的對象就是右值。

double x = 1.3, y = 3.8;
// 以下幾個都是常見的右值
10;                 // 字面常量
x + y;             // 表達式返回值
fmin(x, y);        // 傳值返回函數(shù)的返回值

以下寫法均不能通過編譯:

  1. 10 = 4;x + y = 4;、fmin(x, y) = 4;,VS2015 編譯報錯:error C2106: “=”: 左操作數(shù)必須為左值。原因:右值不能出現(xiàn)在賦值符號的左邊。
  2. &10;、&(x + y);、&fmin(x, y);,VS2015 編譯報錯:error C2102: “&” 要求左值。原因:右值不能取地址。

3.總結

區(qū)分左值和右值,終究還是要看能否取地址。

二、左值引用和右值引用

傳統(tǒng)的 C++ 語法中就存在引用語法,而 C++11標準中新增了右值引用的語法特性,因此為了區(qū)分兩者,將C++11標準出現(xiàn)之前的引用稱為左值引用。

無論左值引用還是右值引用,都是給對象取別名。

1.左值引用

左值引用就是對左值的引用,給左值取別名。

// 以下幾個是對上面左值的左值引用
int& ra = a;
int*& rp = p;
int& r = *p;
const int& rb = b;

2.右值引用

右值引用就是對右值的引用,給右值取別名。

右值引用的表示是在具體的變量類型名稱后加兩個 &,比如:int&& rr = 4;。

// 以下幾個是對上面右值的右值引用
int&& rr1 = 10;
double&& rr2 = x + y;
double&& rr3 = fmin(x, y);

注意:
右值引用引用右值,會使右值被存儲到特定的位置。
也就是說,右值引用變量其實是左值,可以對它取地址和賦值(const右值引用變量可以取地址但不可以賦值,因為 const 在起作用)。
當然,取地址是指取變量空間的地址(右值是不能取地址的)。

比如:

  1. double&& rr2 = x + y;
    &rr2;
    rr2 = 9.4;
    右值引用 rr2 引用右值 x + y 后,該表達式的返回值被存儲到特定的位置,不能取表達式返回值 x + y 的地址,但是可以取 rr2 的地址,也可以修改 rr2 。
  2. const double&& rr4 = x + y;
    &rr4;
    可以對 rr4 取地址,但不能修改 rr4,即寫成rr4 = 5.3;會編譯報錯。

現(xiàn)在我們知道左值引用可以引用左值,右值引用可以引用右值。
那么左值引用是否可以引用右值?右值引用是否可以引用左值呢?
下面的對比與總結給出了答案。

3.對比與總結

左值引用總結:

  1. 左值引用只能引用左值,不能直接引用右值。
  2. 但是const左值引用既可以引用左值,也可以引用右值。
// 1.左值引用只能引用左值
int t = 8;
int& rt1 = t;

//int& rt2 = 8;  // 編譯報錯,因為10是右值,不能直接引用右值


// 2.但是const左值引用既可以引用左值
const int& rt3 = t;

const int& rt4 = 8;  // 也可以引用右值
const double& r1 = x + y;
const double& r2 = fmin(x, y);

問:為什么const左值引用也可以引用右值?
答:在 C++11標準產(chǎn)生之前,是沒有右值引用這個概念的,當時如果想要一個類型既能接收左值也能接收右值的話,需要用const左值引用,比如標準容器的 push_back 接口:void push_back (const T& val)
也就是說,如果const左值引用不能引用右值的話,有些接口就不好支持了。

下面就是 C++98標準中相關接口const左值引用引用右值的例子:

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);

右值引用總結:

  1. 右值引用只能引用右值,不能直接引用左值。
  2. 但是右值引用可以引用被move的左值。

move,本文指std::move(C++11),作用是將一個左值強制轉(zhuǎn)化為右值,以實現(xiàn)移動語義。
左值被 move 后變?yōu)橛抑?,于是右值引用可以引用?/p>

// 1.右值引用只能引用右值
int&& rr1 = 10;
double&& rr2 = x + y;
const double&& rr3 = x + y;

int t = 10;
//int&& rrt = t;  // 編譯報錯,不能直接引用左值


// 2.但是右值引用可以引用被move的左值
int&& rrt = std::move(t);
int*&& rr4 = std::move(p);
int&& rr5 = std::move(*p);
const int&& rr6 = std::move(b);

三、左值引用的使用場景及實際意義

1.使用場景

// 1.左值引用做參數(shù)
void func1(string s)
{...}

void func2(const string& s)
{...}


int main()
{
	string s1("Hello World!");
	func1(s1);  // 由于是傳值傳參且做的是深拷貝,代價較大
	func2(s1);  // 左值引用做參數(shù)減少了拷貝,提高了效率
	
	return 0;
}
// 2.左值引用做返回值(僅限于對象出了函數(shù)作用域以后還存在的情況)
string s2("hello");
// string operator+=(char ch)  傳值返回存在拷貝且是深拷貝
// string& operator+=(char ch)  左值引用做返回值沒有拷貝,提高了效率
s2 += '!';

2.實際意義

傳值傳參和傳值返回都會產(chǎn)生拷貝,有的甚至是深拷貝,代價很大。而左值引用的實際意義在于做參數(shù)和做返回值都可以減少拷貝,從而提高效率。

3.短板

左值引用雖然較完美地解決了大部分問題,但對于有些問題仍然不能很好地解決。

當對象出了函數(shù)作用域以后仍然存在時,可以使用左值引用返回,這是沒問題的。

string& operator+=(char ch)
{
	push_back(ch);
	return *this;
}

但當對象(對象是函數(shù)內(nèi)的局部對象)出了函數(shù)作用域以后不存在時,就不可以使用左值引用返回了。

string operator+(const string& s, char ch)
{
	string ret(s);
	ret.push_back(ch);
	return ret;
}

// 拿現(xiàn)在這個函數(shù)來舉例:ret是函數(shù)內(nèi)的局部對象,出了函數(shù)作用域后會被析構,即被銷毀了
// 若此時再返回它的別名(左值引用),也就是再拿這個對象來用,就會出問題

于是,對于第二種情形,左值引用也無能為力,只能傳值返回。

四、右值引用

于是,為了解決上述傳值返回的拷貝問題,C++11標準就增加了右值引用移動語義。

1.移動語義(Move semantics)

將一個對象中的資源移動到另一個對象(資源控制權的轉(zhuǎn)移)。

(1)移動構造

① 概念

轉(zhuǎn)移參數(shù)右值的資源來構造自己。

// 這是一個模擬string類的實現(xiàn)的移動構造
string(string&& s)
	:_str(nullptr)
	, _size(0)
	, _capacity(0)
{
	swap(s);
}

拷貝構造函數(shù)和移動構造函數(shù)都是構造函數(shù)的重載函數(shù),所不同的是:

  1. 拷貝構造函數(shù)的參數(shù)是 const左值引用,接收左值或右值;
  2. 移動構造函數(shù)的參數(shù)是右值引用,接收右值或被 move 的左值。

注:當傳來的參數(shù)是右值時,雖然拷貝構造函數(shù)可以接收,但是編譯器會認為移動構造函數(shù)更加匹配,就會調(diào)用移動構造函數(shù)。

總的來說,如果這兩個函數(shù)都有在類內(nèi)定義的話,在構造對象時:

  1. 若是左值做參數(shù),那么就會調(diào)用拷貝構造函數(shù),做一次拷貝(如果是像 string 這樣的在堆空間上存在資源的類,那么每調(diào)用一次拷貝構造就會做一次深拷貝)。
  2. 若是右值做參數(shù),那么就會調(diào)用移動構造,而調(diào)用移動構造就會減少拷貝(如果是像 string 這樣的在堆空間上存在資源的類,那么每調(diào)用一次移動構造就會少做一次深拷貝)。

比如執(zhí)行下面這幾行代碼:

string s("Hello World11111111111111111");
string s1 = s;  // s是左值,所以調(diào)用拷貝構造函數(shù)
string s2 = move(s);  // s被move后變?yōu)橛抑?,所以調(diào)用移動構造函數(shù),s的資源會被轉(zhuǎn)移用來構造s2
// 要注意的是,move一般是不這樣用的,因為s的資源被轉(zhuǎn)走了

執(zhí)行string s1 = s;前:詳解 C++ 左值、右值、左值引用以及右值引用
執(zhí)行string s1 = s;后(也是執(zhí)行string s2 = move(s);前):
詳解 C++ 左值、右值、左值引用以及右值引用
執(zhí)行string s2 = move(s);后:
詳解 C++ 左值、右值、左值引用以及右值引用

② 移動構造有無的比較

比如執(zhí)行語句cout << MyLib::to_string(1234) << endl;

只有拷貝構造沒有移動構造:
詳解 C++ 左值、右值、左值引用以及右值引用
在 to_string 函數(shù)棧幀銷毀前,用局部對象 str 拷貝構造出臨時對象返回到函數(shù)調(diào)用處。
詳解 C++ 左值、右值、左值引用以及右值引用
既有拷貝構造也有移動構造:
詳解 C++ 左值、右值、左值引用以及右值引用
在 to_string 函數(shù)棧幀銷毀前,用局部對象 str (反正 str 要銷毀,將 str 視為右值,直接轉(zhuǎn)移 str 的資源 )移動構造出臨時對象返回到函數(shù)調(diào)用處。
詳解 C++ 左值、右值、左值引用以及右值引用

比如執(zhí)行語句MyLib::string ret = MyLib::to_string(1234);

只有拷貝構造沒有移動構造:詳解 C++ 左值、右值、左值引用以及右值引用
在 to_string 函數(shù)棧幀銷毀前,先用局部對象 str 拷貝構造出臨時對象返回到函數(shù)調(diào)用處,to_string 函數(shù)棧幀銷毀后,再用臨時對象拷貝構造出 ret 。
但現(xiàn)在的編譯器一般都會進行優(yōu)化:因為臨時對象有 ret 來接收,這樣的話臨時對象的創(chuàng)建和銷毀就顯得多余了,不如省略掉這一步,直接用 str 拷貝構造出 ret 。
詳解 C++ 左值、右值、左值引用以及右值引用
既有拷貝構造也有移動構造:詳解 C++ 左值、右值、左值引用以及右值引用
在 to_string 函數(shù)棧幀銷毀前,由于局部對象 str 是左值(可以對它取地址),所以用 str 拷貝構造出臨時對象返回到函數(shù)調(diào)用處,to_string 函數(shù)棧幀銷毀后,由于臨時對象是右值,所以用臨時對象移動構造出 ret 。
但現(xiàn)在的編譯器一般都會進行優(yōu)化:因為臨時對象有 ret 來接收,先拷貝構造出臨時對象再用它移動構造出 ret ,臨時對象好像沒必要產(chǎn)生一樣,不如省略掉。既然 str 是 to_string 函數(shù)棧幀的局部對象,最后還是要銷毀,不如將 str 視為右值,直接轉(zhuǎn)移 str 的資源用來構造 ret ,也就是直接用 str 移動構造出 ret 。
詳解 C++ 左值、右值、左值引用以及右值引用

再比如執(zhí)行下面的代碼:

詳解 C++ 左值、右值、左值引用以及右值引用
調(diào)用該函數(shù)后,需要傳值返回這種占用很多資源的自定義類型,
在 C++98 中,沒有移動構造,拷貝構造做深拷貝,花費的代價很大;
在 C++11 中,直接移動構造,轉(zhuǎn)移 m 的資源給 ret ,提高了效率。

(2)移動賦值

① 概念

轉(zhuǎn)移參數(shù)右值的資源來賦給自己。

// 這是一個模擬string類的實現(xiàn)的移動賦值
string& operator=(string&& s)
{
	swap(s);

	return *this;
}

拷貝賦值函數(shù)和移動賦值函數(shù)都是賦值運算符重載函數(shù)的重載函數(shù),所不同的是:

  1. 拷貝賦值函數(shù)的參數(shù)是 const左值引用,接收左值或右值;
  2. 移動賦值函數(shù)的參數(shù)是右值引用,接收右值或被 move 的左值。

注:當傳來的參數(shù)是右值時,雖然拷貝賦值函數(shù)可以接收,但是編譯器會認為移動賦值函數(shù)更加匹配,就會調(diào)用移動賦值函數(shù)。

總的來說,如果這兩個函數(shù)都有在類內(nèi)定義的話,在進行對象的賦值時:

  1. 若是左值做參數(shù),那么就會調(diào)用拷貝賦值,做一次拷貝(如果是像 string 這樣的在堆空間上存在資源的類,那么每調(diào)用一次拷貝賦值就會做一次深拷貝)。
  2. 若是右值做參數(shù),那么就會調(diào)用移動賦值,而調(diào)用移動賦值就會減少拷貝(如果是像 string 這樣的在堆空間上存在資源的類,那么每調(diào)用一次移動賦值就會少做一次深拷貝)。

比如下面這幾行代碼:

string s("11111111111111111");
string s1("22222222222222222");
s1 = s;  // s是左值,所以調(diào)用拷貝賦值函數(shù)

string s2("333333333333333333");
s2 = std::move(s);  // s被move后變?yōu)橛抑?,所以調(diào)用移動賦值函數(shù),s的資源會被轉(zhuǎn)移用來賦給s2
// 要注意的是,move一般是不這樣用的,因為s的資源被轉(zhuǎn)走了
② 移動賦值有無的比較

比如執(zhí)行下面的語句:
MyLib::string ret("111111111111111111111111");
ret = MyLib::to_string(12345);

沒有移動賦值(有移動構造和拷貝賦值):
詳解 C++ 左值、右值、左值引用以及右值引用
用 str(編譯器視 str 為右值)移動構造出臨時對象作為返回值,再用臨時對象拷貝賦值給 ret 。
詳解 C++ 左值、右值、左值引用以及右值引用
有移動賦值:
詳解 C++ 左值、右值、左值引用以及右值引用
用 str(編譯器視 str 為右值)移動構造出臨時對象作為返回值,由于臨時對象是右值,再用臨時對象移動賦值給 ret 。
詳解 C++ 左值、右值、左值引用以及右值引用

2.右值引用的使用場景

除了上面的使用場景之外,C++11標準的STL 容器的相關接口函數(shù)也增加了右值引用版本。

比如:

詳解 C++ 左值、右值、左值引用以及右值引用詳解 C++ 左值、右值、左值引用以及右值引用

3.完美轉(zhuǎn)發(fā)(Perfect forwarding)

(1)引入原因

在此之前我們需要知道什么是萬能引用:

確定類型的 && 表示右值引用(比如:int&& ,string&&),
但函數(shù)模板中的 && 不表示右值引用,而是萬能引用,模板類型必須通過推斷才能確定,其接收左值后會被推導為左值引用,接收右值后會被推導為右值引用

注意區(qū)分右值引用和萬能引用:下面的函數(shù)的 T&& 并不是萬能引用,因為 T 的類型在模板實例化時已經(jīng)確定。

template<typename T>
class A
{
	void func(T&& t);  // 模板實例化時T的類型已經(jīng)確定,調(diào)用函數(shù)時T是一個確定類型,所以這里是右值引用
};

讓我們通過下面的程序來認識萬能引用:

template<typename T>
void f(T&& t)  // 萬能引用
{
	//...
}

int main()
{
	int a = 5;  // 左值
	f(a);  // 傳參后萬能引用被推導為左值引用
	
	const string s("hello");  // const左值
	f(s);  // 傳參后萬能引用被推導為const左值引用
	
	f(to_string(1234));  // to_string函數(shù)會返回一個string臨時對象,是右值,傳參后萬能引用被推導為右值引用

	const double d = 1.1;
	f(std::move(d));  // const左值被move后變成const右值,傳參后萬能引用被推導為const右值引用
	
	return 0;
}

在調(diào)試下開監(jiān)視窗口可看到傳參后參數(shù) t 的類型:詳解 C++ 左值、右值、左值引用以及右值引用

于是我們會用萬能引用去做一些有意義的事,比如下面的代碼:

void Func(int& x) {	cout << "左值引用" << endl; }

void Func(const int& x) { cout << "const左值引用" << endl; }

void Func(int&& x) { cout << "右值引用" << endl; }

void Func(const int&& x) { cout << "const右值引用" << endl; }


template<typename T>
void f(T&& t)  // 萬能引用
{
	Func(t);  // 根據(jù)參數(shù)t的類型去匹配合適的重載函數(shù)
}

int main()
{
	int a = 4;  // 左值
	f(a);
	
	const int b = 8;  // const左值
	f(b);
	
	f(10); // 10是右值
	
	const int c = 13;
	f(std::move(c));  // const左值被move后變成const右值
	
	return 0;
}

運行程序后,我們本以為打印的結果是:
左值引用
const左值引用
右值引用
const右值引用

但實際的結果卻是:
詳解 C++ 左值、右值、左值引用以及右值引用
后兩行的運行結果跟我們預想的不一樣。

那么這是怎么一回事呢?
其實在本文的前面已經(jīng)講過了,右值引用變量其實是左值,所以就有了上面的運行結果。

具體解釋:

  1. f(10);
    10是右值,傳參后萬能引用被推導為右值引用,但該右值引用變量其實是左值,因此實際調(diào)用的函數(shù)是void Func(int& x)。
  2. f(std::move(c));
    const左值被move后變成const右值,傳參后萬能引用被推導為const右值引用,但該const右值引用變量其實是const左值,因此實際調(diào)用的函數(shù)是void Func(const int& x)

也就是說,右值引用失去了右值的屬性

但我們希望的是,在傳遞過程中能夠保持住它的原有的左值或右值屬性,于是 C++11標準提出完美轉(zhuǎn)發(fā)。

(2)概念

完美轉(zhuǎn)發(fā)是指在函數(shù)模板中,完全依照模板的參數(shù)類型,將參數(shù)傳遞給當前函數(shù)模板中的另外一個函數(shù)。

因此,為了實現(xiàn)完美轉(zhuǎn)發(fā),除了使用萬能引用之外,我們還要用到std::forward(C++11),它在傳參的過程中保留對象的原生類型屬性。

這樣右值引用在傳遞過程中就能夠保持右值的屬性。

void Func(int& x) { cout << "左值引用" << endl; }

void Func(const int& x) { cout << "const左值引用" << endl; }

void Func(int&& x) { cout << "右值引用" << endl; }

void Func(const int&& x) { cout << "const右值引用" << endl; }


template<typename T>
void PerfectForward(T&& t)  // 萬能引用
{
	Func(std::forward<T>(t));  // 根據(jù)參數(shù)t的類型去匹配合適的重載函數(shù)
}

int main()
{
	int a = 4;  // 左值
	PerfectForward(a);

	const int b = 8;  // const左值
	PerfectForward(b);

	PerfectForward(10); // 10是右值

	const int c = 13;
	PerfectForward(std::move(c));  // const左值被move后變成const右值

	return 0;
}

運行結果如下:
詳解 C++ 左值、右值、左值引用以及右值引用

實現(xiàn)完美轉(zhuǎn)發(fā)需要用到萬能引用和 std::forward 。

(3)使用場景

除了上面的使用場景之外,C++11標準的 STL 容器的相關接口函數(shù)也實現(xiàn)了完美轉(zhuǎn)發(fā),這樣就能夠真正實現(xiàn)右值引用的價值。

比如 STL 庫中的容器 list :
詳解 C++ 左值、右值、左值引用以及右值引用

上面四個接口函數(shù)都調(diào)用 _Insert 函數(shù),_Insert 函數(shù)模板實現(xiàn)了完美轉(zhuǎn)發(fā)。

再比如自己模擬實現(xiàn)的 list(這里只寫出主要部分):

template<class T>
struct ListNode
{
	ListNode* _next = nullptr;
	ListNode* _prev = nullptr;
	T _data;
};


template<class T>
class List
{
	typedef ListNode<T> Node;
public:
	List()
	{
		_head = new Node;
		_head->_next = _head;
		_head->_prev = _head;
	}

	void PushBack(const T& x)  // 左值引用
	{
		Insert(_head, x);
	}

	void PushFront(const T& x)  // 左值引用
	{
		Insert(_head->_next, x);
	}

	void PushBack(T&& x)  // 右值引用
	{
		Insert(_head, std::forward<T>(x));  // 關鍵位置:保留對象的原生類型屬性
	}

	void PushFront(T&& x)  // 右值引用
	{
		Insert(_head->_next, std::forward<T>(x));  // 關鍵位置:保留對象的原生類型屬性
	}

	template<class TPL>    // 該函數(shù)模板實現(xiàn)了完美轉(zhuǎn)發(fā)
	void Insert(Node* pos, TPL&& x)  // 萬能引用
	{
		Node* prev = pos->_prev;
		Node* newnode = new Node;
		newnode->_data = std::forward<TPL>(x);  // 關鍵位置:保留對象的原生類型屬性

		// prev newnode pos
		prev->_next = newnode;
		newnode->_prev = prev;
		newnode->_next = pos;
		pos->_prev = newnode;
	}

private:
	Node* _head;
};

只要是右值引用,由當前函數(shù)再傳遞給其它函數(shù)調(diào)用,要保持右值屬性,必須實現(xiàn)完美轉(zhuǎn)發(fā)。

4.重大意義

右值引用(及其支持的移動語義和完美轉(zhuǎn)發(fā))是 C++11 中加入的最重要的新特性之一,它使得 C++ 程序的運行更加高效。文章來源地址http://www.zghlxwxcb.cn/news/detail-402998.html

到了這里,關于詳解 C++ 左值、右值、左值引用以及右值引用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • MordernC++之左值(引用)與右值(引用)

    C++中左值與右值的概念是從C中繼承而來,一種簡單的定義是 左值能夠出現(xiàn)再表達式的左邊或者右邊,而右值只能出現(xiàn)在表達式的右邊 。 另一種區(qū)分左值和右值的方法是: 有名字、能取地址的值是左值,沒有名字、不能取地址的值是右值 。比如上述語句中a,b, c是變量可以

    2023年04月09日
    瀏覽(19)
  • 【C++11】左值引用和右值引用

    【C++11】左值引用和右值引用

    需要云服務器等云產(chǎn)品來學習Linux的同學可以移步/--騰訊云--/--阿里云--/--華為云--/官網(wǎng),輕量型云服務器低至112元/年,新用戶首次下單享超低折扣。 ??? 目錄 一、新的類功能 1、新的默認成員函數(shù) 2、類成員變量初始化 3、強制生成默認函數(shù)的default 4、禁止生成默認函

    2023年04月17日
    瀏覽(24)
  • 【送書】【C++11】左值引用和右值引用

    【送書】【C++11】左值引用和右值引用

    需要云服務器等云產(chǎn)品來學習Linux的同學可以移步/--騰訊云--/--阿里云--/--華為云--/官網(wǎng),輕量型云服務器低至112元/年,新用戶首次下單享超低折扣。 ??? 目錄 一、新的類功能 1、新的默認成員函數(shù) 2、類成員變量初始化 3、強制生成默認函數(shù)的default 4、禁止生成默認函

    2023年04月09日
    瀏覽(18)
  • 左值引用、右值引用,std::move() 的匯編解釋

    左值引用、右值引用,std::move() 的匯編解釋

    1:左值引用 引用其實還是指針,但回避了指針這個名字。由編譯器完成從地址中取值。以vs2019反匯編: 如圖,指針和引用的匯編代碼完全一樣。但引用在高級語言層面更友好,對人腦。比如可以少寫一個 * 號和 - 。 ,以下是指針和引用的使用: 以上就是左值引用,引用的

    2024年02月04日
    瀏覽(15)
  • C++ 左值和右值

    C++ 左值和右值

    在C++11中所有的值必屬于左值、右值兩者之一,右值又可以細分為純右值、將亡值。在C++11中可以取地址的、有名字的就是左值,反之,不能取地址的、沒有名字的就是右值(將亡值或純右值)。舉個例子,int a = b+c, a 就是左值,其有變量名為a,通過a可以獲取該變量的地址;

    2024年02月14日
    瀏覽(14)
  • C++左值右值完美轉(zhuǎn)發(fā)轉(zhuǎn)移

    英文含義: 左值(Lvalue) : Locator value ,意味著它指向一個具體的內(nèi)存位置。 右值(Rvalue) : Read value ,指的是可以讀取的數(shù)據(jù),但不一定指向一個固定的內(nèi)存位置。 定義 左值 :指的是一個持久的內(nèi)存地址。左值可以出現(xiàn)在賦值操作的左側或右側。例如,變量、數(shù)組的元

    2024年03月10日
    瀏覽(35)
  • C++面試八股文:什么是左值,什么是右值?

    某日二師兄參加XXX科技公司的C++工程師開發(fā)崗位第16面: 面試官:什么是左值,什么是右值? 二師兄:簡單來說,左值就是可以使用 符號取地址的值,而右值一般不可以使用 符號取地址。 二師兄:一般左值存在內(nèi)存中,而右值存在寄存器中。 二師兄:嚴格意義上分,右值

    2024年02月09日
    瀏覽(17)
  • C++:深入理解C++11新特性:Chapter3:左值和右值

    C++:深入理解C++11新特性:Chapter3:左值和右值

    在C語言中,我們常常會提起左值(lvalue),右值(rvalue)這樣的稱呼,而在編譯程序時,編譯器有時也會報出錯誤信息中包含 左值,右值說法。不過左值、右值通常不是通過一個嚴謹?shù)亩x而為人所知。下面我通過這樣一個例子,來引導大家認識: 左值,右值,左值引用,右

    2024年02月04日
    瀏覽(102)
  • C++右值引用,右值引用與const引用的區(qū)別

    左值:可以取地址的、有名字的變量,有持久性; 右值:一般是不可尋址的常量,或在表達式求值過程中創(chuàng)建的無名臨時對象,短暫性的。 C++11新增了另一種引用——右值引用。這種引用可指向右值,使用聲明。 右值引用只能引用臨時變量和常量值。 const引用:可以引用普

    2024年01月18日
    瀏覽(26)
  • C++右值引用(&&)

    右值引用是 C++11 新增的特性之一,它是我們在日常開發(fā)工作中不斷接觸到的特性之一。本篇博客將對右值引用的定義、使用場景以及使用方法進行詳細介紹。 右值引用是一種新的引用類型,“右值引用” 又被稱為“具名右值引用”(Named Rvalue Reference),其定義形式為:Type v

    2024年02月07日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包