参考文献

现代 C++ 教程:高速上手 C++ 11/14/17/20

右引用

问题的开始

好久没有练习c++,在数据结构中学习到了串这个数据结构,我便使用c++自己慢慢摸索实现了一下。当然我也遇到了不少问题。

在coding的时候要时不时查阅自己的c++ 笔记,当然我也遇到了没有学习过的知识点,特此记录一下!

下面图片中 S1 S2 S3 都是自己正在完善的 String类的变量

image-20210330200831534

S4 = S1 + S3;std::cout << S1 + S2<<std::endl; 都发生了报错

你一定会说,你没有重载 =哇! 可惜我重载了

	String& String::operator= (String& source)
	{
#ifdef DeBug
		std::cout << "\ncall String& String::operator= (String& source)" << std::endl;
#endif // DeBug

		if (&source == this)//本来就是自己
			return *this;

		lenght = 0;
		delete[] chars;

		chars = new char[source.lenght+1];
		for (int i = 0; i < source.lenght; i++)
			chars[i] = source.chars[i];
		chars[source.lenght] = '\0';
		lenght = source.lenght;
		return *this;
	}//重载等于 = 左值

按道理重载了= 上述语句应该没有错误的。这里涉及到左值和右值的问题

当然,我上学期学习c++的时候也遇到这类问题,请教老师,结果老师不理我,AHH,于是问题就留到了今天。

左值和右值

要弄明白右值引用到底是怎么一回事,必须要对左值和右值做一个明确的理解。

左值(lvalue, left value),顾名思义就是赋值符号左边的值。准确来说, 左值是表达式(不一定是赋值表达式)后依然存在的持久对象。

对左值和右值的一个最常见的误解是:等号左边的就是左值,等号右边的就是右值。

而 C++11 中为了引入强大的右值引用,将右值的概念进行了进一步的划分,分为:纯右值、将亡值。

纯右值(prvalue, pure rvalue),纯粹的右值,要么是纯粹的字面量,例如 10, true; 要么是求值结果相当于字面量或匿名临时对象,例如 1+2。非引用返回的临时变量、运算表达式产生的临时变量、 原始字面量、Lambda 表达式都属于纯右值。

我们后续讨论 将亡值这种右值

左值和右值都是针对表达式而言的,左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时就不再存在的临时对象,人家毕竟叫将亡值。

这样实在时太难理解了,还是来一点例子吧:

int a = 10;  
int *p = &a;
int a=b+c;
a++;
++a;

请问 a, a++, p, &a, b+c 谁是右值。

我们这里又一个非常好判断的秘诀:无法取地址的变量是右值右值是指表达式结束时就不再存在的临时对象(无法持久存在) ,所以取不了地址.

  1. a 可以取地址 ,左值
  2. &a 使用过之后就不存在了 ,无法取地址 ,右值
  3. p 左值
  4. b+c 无法取地址 ,右值
  5. a++ ,是先取出持久对象a的一份拷贝,再使持久对象a的值加1,最后返回那份拷贝,而那份拷贝是临时对象(不可以对其取地址),故其是右值;
  6. ++a,a则是使持久对象a的值加1,并返回那个持久对象a本身(可以对其取地址),故其是左值;

右引用

变量分左值和右值,那么引用也得分左右。

刚开始学习c++,书上就讲了左引用 . 也就常见 int&,那么右引用如何表示呢?int&&

不要认为ta是对地址的引用哇QWQ.

所以回到刚开的问题,为啥哪里还会报错?当然就是我仅仅重载了 左值=,所以再重载一个右值= 就解决了。

	String& String::operator = (String&& source)
	{
#ifdef DeBug
		std::cout << "\ncall String& String::operator = (String&& source)" << std::endl;
#endif // DeBug

		lenght = source.lenght;
		chars = source.chars;

		source.lenght = 0;
		source.chars = nullptr;
		return *this;
	}//重载 =右值

结语

这本 电子版的 现代 C++ 教程: 高速上手 是非常不错的,希望自己能够精通C++ (doge)

image-20210330204233799

努力成长的程序员