一点点小细节,不知道说的对不对。
首先我们看到最熟悉的前置递增和后置递增
int i = 0;
++i;
i++;
这两种递增的实现这里不再赘述。
我们要讲的是下面这两种情况。
int i = 0;
++(++i);
cout << i;//2
在连续两次使用前置递增之后,i的值确实是发生了两次变化的,进行了两次递增,值从原来的0变成了2
然后我们用同样的形式在后置递增上试一遍
int i = 0;
(i++)++;//报错
作为(i++)是无法作为后置递增的左值的,而事实上是i++无法作为任何式子的左值。
至于为什么可以查看
i++为什么不能作为左值,而++i可以作为左值 - SupremeBoy - 博客园 (cnblogs.com)
简单来说因为i++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通过地址对它进行操作.(换句话说就是不能作为左值)。
int temp;
temp=i;
i=i+1;
return temp;
而++i返回的是i,它是程序中定义的可寻址变量的引用,所以它可以作为左值。
a=a+1;
return i;
那么到这里我们就知道了C++自带的前置递增是可以实现链式编程的,而后置递增却不能。
接下来我们把这写前置知识带入到运算符重载当中
#include <iostream>
using namespace std;
class Box
{
public:
Box(int width = 0, int height = 0)
{
m_width = width;
m_height = height;
}
friend ostream& operator<<(ostream& output, const Box& box)
{
cout << "width : " << box.m_width << " height : " << box.m_height << endl;
return output;
}
Box& operator++()
{
m_width++;
m_height++;
return *this;
}
Box operator++(int)
{
Box temp = *this;
++(*this);
return temp;
}
int m_width;
int m_height;
};
上面的代码是在类内对<<,前置++,后置++的实现。
然后我们进行尝试使用
int main()
{
Box box1(3,3);
cout << box1;
box1++;
cout << box1;
++box1;
cout << box1;
}
//输出
//width : 3 height : 3
//width : 4 height : 4
//width : 5 height : 5
对于单次的递增前置后置能实现。那么来到多次的情况。
int main()
{
Box box1(3,3);
cout << box1;
(box1++)++;
cout << box1;
++(++box1);
cout << box1;
}
//输出
//width : 3 height : 3
//width : 4 height : 4
//width : 6 height : 6
发现在(box1++)++语句执行后,box1只递增了一次。这是第一个问题。
我们在这可以实现后置递增的链式编程与之前i++会报错不一样。这是第二个问题。
首先第二个问题
(box1++)++//运行
(i++)++//报错
其实我也不知道为什么这里的第一行不会报错,因为经过我的测试,box1++返回的是拷贝构造的一个对象,而这个对象是不能当左值的,因为你的拷贝对象在函数中是局部变量已经没了。因此你是不能被修改的
就像(i++)++
但这里为什么能我也不知道,我也只是个学了两个月的C++新手,到时候知道了再评论,或者哪位来讲一下。
然后回答第一个问题
因为你进行一次box1++操作后返回的其实是拷贝过后的对象,不是你原来的对象了,所以你的操作没有加在你原来的的对象上而是被拷贝的对象上,因此你的操作时,给原来的box1++,给你的拷贝对象++。等于你只给原来的加了一次,所以只变化1。