網(wǎng)站首頁 編程語言 正文
左值引用和右值引用
左值與右值
左值:在內(nèi)存中占有確定位置的對象,即左值占有內(nèi)存。換句話來說,就是有地址,有值。
右值:不占內(nèi)存(科學(xué)地講是臨時寄存器),僅有值,為臨時變量。
左右值的切換
右值->左值:用*符號。
int a=10;
int* b=&a;// b為右值。
*b=20;// b為右值,*b為左值。
左值->右值:用&符號。
int a = 10;
&a = 40; //錯誤:賦值操作要求一個左值
int* b = &(a + 1); //錯誤:‘&'運(yùn)算符要求一個左值,a為左值,但a+1為右值。
int* c = &a; //正確:var是左值
左值引用:將左值綁定在引用上
第一種情況,函數(shù)返回右值。
int global = 10;
int test()
{
return global;// 返回右值
}
int main()
{
test() = 20;// error,右值不可賦值!
cout << "test為:"<<test();
return 0;
}
第二種情況,函數(shù)返回左值。
int global = 10;
int& test()
{
return global;// 返回左值
}
int main()
{
test() = 20;// 左值可賦值
cout << "test為:"<<test();
return 0;
}
測試:
說明了左值引用讓函數(shù)調(diào)用可以賦值成為可能。
常量左值引用和非常量左值引用
int a1=20; //非常量左值
const int a2=20; //常量左值
const int a3=20; //常量左值
//非常量左值引用
int &b1=a1; //正確,a1是一個非常量左值,可以被非常量左值引用綁定
int &b2=a2; //錯誤,a2是一個常量左值,不可以被非常量左值引用綁定
int &b3=20; //錯誤,10是一個非常量右值,不可以被非常量左值引用綁定
int &b4=a2+a3; //錯誤,(a2+a3)是一個常量右值,不可以被非常量左值引用綁定
//常量左值引用
const int &c1=a1; //正確,a1是一個非常量左值,可以被非常量右值引用綁定
const int &c2=a2; //正確,a2是一個常量左值,可以被非常量右值引用綁定
const int &c3=a1+a2; //正確,(a1+a2)是一個非常量右值,可以被常量右值引用綁定
const int &c4=a2+a3; //正確,(a2+a3)是一個常量右值,可以被非常量右值引用綁定
總結(jié):
- 1.非常量左值引用只能綁定到非常量左值上;
- 2.常量左值引用可以綁定到非常量左值、常量左值、非常量右值、常量右值等所有類型。
(大->小,小引用綁大左值,常量左值范圍更小嘛)
右值引用:將右值綁定在引用上
常量右值引用和非常量右值引用
總結(jié):
- 1.非常量右值引用只能綁定到非常量右值上;
- 2.常量右值引用可以綁定到非常量右值、常量右值上。
移動構(gòu)造函數(shù)
小狗狗類:
Dog(int age,string name) :m_age(new int(age)), m_name(name){}
Dog(Dog& d):m_age(d.m_age),m_name(d.m_name)
{
cout << "我是拷貝構(gòu)造函數(shù)······" << endl;
}
Dog(Dog&& d) :m_age(d.m_age), m_name(d.m_name)
{
d.m_age = nullptr;
cout << "我是移動構(gòu)造函數(shù)······" << endl;
}
int* m_age;
string m_name;#include<string>
#include<iostream>
using namespace std;
class Dog
{
public:
Dog(){};
Dog(int age,string name) :m_age(new int(age)), m_name(name){}
Dog(Dog& d):m_age(d.m_age),m_name(d.m_name)
{
cout << "我是拷貝構(gòu)造函數(shù)······" << endl;
}
Dog(Dog&& d) :m_age(d.m_age), m_name(d.m_name)
{
d.m_age = nullptr;
cout << "我是移動構(gòu)造函數(shù)······" << endl;
}
int* m_age;
string m_name;
};
客戶端類:
#include"construct.h"
int main()
{
int age = 19;
string name = "小狗狗";
Dog d1(age, name);
cout << "d1:" <<* d1.m_age << d1.m_name << endl;
Dog d2(move(d1));
bool is = d1.m_age == nullptr;
cout << is << endl;
cout << "d2.age:" << *d2.m_age <<endl<< "d2.name:" <<d2.m_name << endl;
return 0;
}
測試:
說明了移動構(gòu)造運(yùn)行成功,d1銷毀了,d2獲取到了d1的內(nèi)存。
賦值和移動賦值函數(shù)
賦值函數(shù)類:
#include<String>
using namespace std;
class Cat
{
public:
Cat(){}
Cat(int age ,string name):age(age),name(name) {}
Cat& operator=(Cat& c)
{
if (this!= &c)
{
age = c.age;
name = c.name;
}
return *this;
}
int age;
string name;
};
移動賦值函數(shù)類:
#include"assign.h"
class Dog
{
public:
Dog() {}
Dog(int age, string name) :age(new int(age)), name(name) {}
Dog& operator=(Dog&& c)
{
age = c.age;
name = c.name;
c.age = nullptr;
return *this;
}
int* age;
string name;
};
客戶端類:
#include<iostream>
#include"moveAssign.h"
int main()
{
cout << "賦值函數(shù)" << endl;
Cat c1(18, "小貓咪");
Cat c2 ;
c2 = c1;
cout << "c1.age:" << c1.age << endl << "c1.name" << c1.name << endl;
cout << "c2.age:" << c2.age << endl << "c2.name" << c2.name << endl<<endl;;
cout << "移動賦值函數(shù)" << endl;
Dog d1(19,"小狗狗");
cout << "d1.age:" << *d1.age << endl << "d1.name" << d1.name << endl << endl;
Dog d2;
d2 = move(d1);
bool is = (d1.age == nullptr);
cout << "d1是否為空:" << is << endl;
cout << "d2.age:" << *d2.age << endl << "d2.name" << d2.name << endl;
return 0;
}
測試:
原文鏈接:https://blog.51cto.com/u_15558033/5631962
相關(guān)推薦
- 2022-06-24 SingleFlight模式的Go并發(fā)編程學(xué)習(xí)_Golang
- 2023-04-08 Python實(shí)現(xiàn)將一段話txt生成字幕srt文件_python
- 2022-04-20 Django學(xué)習(xí)之路之請求與響應(yīng)_python
- 2022-03-22 C語言字符串函數(shù)入門_C 語言
- 2022-05-25 Jenkins 把本地項(xiàng)目構(gòu)建好上傳到云服務(wù)器并執(zhí)行shell腳本啟動項(xiàng)目
- 2022-07-11 Python如何獲取多線程返回結(jié)果_python
- 2023-01-29 Python?find()、rfind()方法及作用_python
- 2022-07-17 Android?studio實(shí)現(xiàn)簡單計(jì)算器的編寫_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支