文章目录
1、区分左右值
什么是左值?
左值是一个数据的表达式,能被取地址和赋值。
左值引用就是给左值取别名。
int main()
{
//以下a、b、p、*p都是左值
int a = 1;
const int b = 2;
int* p = new int;
//以下ra、rb、rp、value都是左值引用
//并且看到左值a、b、p、*p也都可以出现在赋值右边
//所以左值既可以在赋值左边,也可以在赋值右边
int& ra = a;
const int& rb = b;
int*& rp = p;
int& value = *p;
}
左值重点:
能被取地址的才是左值。
左值既可以出现在赋值左边,也可以出现在赋值右边。
什么是右值?
右值也是一个数据的表达式,右值不能取地址,如:字面常量、表达式返回值,函数返回值等
int main()
{
int x = 1, y = 2;
//这种字面值常量、函数返回值、表达式都是右值
10;
fmin(1, 2);
x + y;
//右值引用只能引用右值
int&& rra = 10;
int&& rrm = fmin(1, 2);
int&& rrb = x + y;
}
右值不能被取地址
右值只能放在赋值右边
左值引用能引用左值和右值,右值引用只能引用右值
左值引用是给左值取别名,右值引用是给右值取别名。
int main()
{
int x = 1, y = 2;
int a = 1;
//const左值引用能引用左值
const int& ra = a;
//const左值引用能引用右值 本质是权限的缩小
const int& rb = x + y;
const int& rc = 10;
//右值引用只能引用右值
int&& rrd = x + y;
//int&& rrd = a; //err 无法将右值引用绑定到左值
//但是右值引用能引用move修饰的左值
int&& rre = move(a);
}
左值引用能引用左值
const左值引用即能引用左值,也能引用右值
右值引用除了引用右值,还可以引用move修饰后的左值。
2、右值引用
左值引用的意义是什么? 函数传参/函数传返回值 – 减少拷贝
template<class T>
void func1(const T& x)
{
// ...
}
template<class T>
const T& func2(const T& x)
{
// ...
return x;
}
但是左值引用没有彻底解决函数中局部对象返回的问题:
template<class T>
T func3(const T& x)
{
T temp;
// ...
return temp;
}
右值引用的意义就是为了补齐这个短板
2.1 右值引用的作用
先来看一段代码
#include <iostream>
#include <assert.h>
using namespace std;
namespace test
{
class string
{
public:
typedef char* iterator;
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
string(const char* str = "")
:_size(strlen(str))
, _capacity(_size)
{
_str = new char[_capacity + 1];
strcpy(_str, str);
}
// s1.swap(s2)
void swap(string& s)
{
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
// 拷贝构造
string(const string& s)
{
cout << "string(const string& s) -- 深拷贝" << endl;
string tmp(s._str);
swap(tmp);
}
// 赋值重载
string& operator=(const string& s)
{
cout << "string& operator=(string s) -- 深拷贝" << endl;
string tmp(s._str);
swap(tmp);
return *this;
}
~string()
{
delete[] _str;
_str = nullptr;
}
char& operator[](size_t pos)
{
assert(pos < _size);
return _str[pos];
}
void reserve(size_t n)

文章详细介绍了C++11中的右值引用,包括左值和右值的概念,右值引用的作用,如减少拷贝提高效率,以及右值引用的左值属性。此外,还讨论了万能引用和完美转发的概念,以及默认移动构造和移动赋值的使用。
最低0.47元/天 解锁文章
88





