文章目录
一、左值引用、 右值引用
1.1 左值与右值
我们经常能听到左值和右值,那么我们怎么判断左值和右值呢?
C++中还有一个被广泛认同的说法, 那就是可以取地址的、 有名字的就是左值, 反之,不能取地址的、 没有名字的就是右值。
左值可以出现在左边和右边,而右值不能出现在左边。
举个例子:
a是个左值a+b就是个右值
因为可以对a取地址:&a
但是不能对a + b取地址:&(a + b)
左值和右值不是个变量,而是个数据表达式。
左值一般有:变量名或解引用的指针
右值一般有:字面常量、表达式返回值,函数返回值
1.2 左值引用
左值引用就是给左值起别名。
int main()
{
// 左值
int a = 0;
int* b = nullptr;
const int c = 1;
const int* d = nullptr;
// 左值引用
int& ra = a;
int*& rb = b;
const int& rc = c;
const int*& rd = d;
// 左值引用不能引用右值,但const左值引用可以
//int& e = 10;
//int& f = (a + c);
const int& e = 10;
const int& f = (a + c);
return 0;
}
1.3 右值引用
右值引用只能引用右值,不能引用左值。
但是右值引用可以move以后的左值,move可以把ret变成一个将亡值(右值)。
int main()
{
// 只能引用右值
int&& a = 10;
a++;// 右值引用后变左值
int ret = 0;
//int&& b = ret;// 不能引用左值
// 可以引用move后的左值
int&& b = std::move(ret);
return 0;
}
const引用既可以引用左值也可以引用右值。
二、右值引用的意义
我们以前使用的引用基本上都是左值引用(函数传参,函数传返回值),左值引用的作用主要用来减少拷贝。
但是左值引用并没有彻底的解决:传返回值的时候,如果是一个局部变量,我们就无法引用返回了。
template <class T>
T& fun()
{
T a;
return a;
}
这里出了作用域后对象自动销毁,所以不能传递回去造成越界访问。
为了解决这种情况,我们就需要右值引用,接下来用我们之前写过的string类举例子,方便观察。
namespace yyh
{
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);
}
void swap(string& s)
{
::swap(_str
最低0.47元/天 解锁文章
181

被折叠的 条评论
为什么被折叠?



