目录
1.右值和左值
2.左值引用和右值引用
3.左右值的交叉引用的具体情景
3.4当不接受返回值就没有办法优化
左值与右值是C语言中的概念,但C标准并没有给出严格的区分方式,一般认为:可以放在=左边的,或者能 够取地址的称为左值,只能放在=右边的,或者不能取地址的称为右值,但是也不一定完全正确。
左值:可以取地址,可以赋值的
int a = 10;int& r1 = a;int* p = &a;int& r2 = *p;const int b = 10;const int& r3 = b;
右值:不能取地址的值
//常见的右值10;x + y;fmin(x, y);
左值引用使用:&,右值引用使用:&&;同是他们也是可以交叉引用
//左值引用左值int a=1;int& b=a;int* c=&a;int& d=*c;//右值引用右值int X=10,int Y=20;int&& a1=10;int&& b1=X+Y;int&& c1=min(X,Y);
2.1左右值的交叉引用
左值引用右值-- 不能直接引用,但是const 左值引用可以引用右值
右值引用左值-- 不能直接引用,但是可以右值引用可以引用move以后左值
//左值引用右值-- 不能直接引用,但是const 左值引用可以引用右值const int& a=2;//右值引用左值-- 不能直接引用,但是可以右值引用可以引用move以后左值int a1=10;int&& b1=move(a1)
3.1左值引用右值的具体情景
3.2右值引用左值的具体情景
class string{public:// 拷贝构造string(const string& s):_str(nullptr), _size(0), _capacity(0){cout << "string(const string& s) -- 深拷贝" << endl;string tmp(s._str);swap(tmp);}// 移动构造string(string&& s):_str(nullptr), _size(0), _capacity(0){cout << "string(string&& s) -- 资源转移" << endl;string operator+(char ch){string tmp(*this);push_back(ch);return tmp;}private:char* _str;size_t _size;size_t _capacity; // 不包含最后做标识的\0};
3.1移动构造:资源转移,没有了深拷贝和delete效率大大提高
3.2如果没有移动构造,调用重载+返回值是一个将亡值(右值),被s1接受,会调用两次拷贝构造(左值引用右值),但是编译器会有优化会当重载函数快结束的时候使用将亡值构造是s1;
3.3如果有了移动构造,调用重载+返回值是一个将亡值(右值),被s1接受,会调用一次拷贝构造和一次移动构造,但是编译器会有优化会当重载函数快结束的时候使用将亡值移动构造是s1,资源转移比深拷贝效率更高;
3.5push_back的右值引用的重载