运算符重载前++与后++

无论前++还是后++,操作数都只有一个,这样我们做运算符重载的时候,该如何区分呢?这里就要接受一个新的知识,就是亚元。在C++ Primer一书中是这样描述的(中文版 第五版 503 页)“为了解决这个问题,后置版本接受一个额外的(不被使用)int类型的形参。当我们使用后置运算符时,编译器为这个形参提供一个值为0的实参。尽管从语法上来说后置函数可以使用这个额外的形参,但是在实际过程中通常不会这么做。这个形参唯一的作用就是区分前置版本和后置版本的函数,而不是真的要在实现后置版本时参与运算。”下面便是前++和后++的实现代码,请注意两种实现不同的区别,一个是返回引用,一个是返回临时对象:

#include <iostream>

using namespace std;

class Complex
{
public:
	Complex(float x, float y)
		:_x(x), _y(y) {}
	
	void display()
	{
		cout << "(x = " << _x << ", y = " << _y << ")" << endl;
	}

	// 一定要返回引用,因为++会改变操作数,而如果是临时对象,操作数据的值不会变
	// 前++
	Complex& operator++()
	{
		++this->_x;
		++this->_y;
		return *this;
	}

	// 后++,在参数中随便加一个类型,表示是后++,称为亚元
	 const Complex operator++(int)
	{
		// 先保存一个*this的临时变量
		Complex tmp(*this);
		// 对this自身++
		this->_x++;
		this->_y++;
		// 返回临时的变量
		return tmp;
	}

private:
	float _x;
	float _y;
};

int main(int argc, char* argv[])
{
	/*
	基础数据类型,前++
	int n = 10;
	cout << n << endl;		// 10
	cout << ++n << endl;	// 11
	cout << n << endl;		// 11
	cout << ++++n << endl;	// 13
	*/

	Complex c1(10, 0);
	++c1;
	c1.display();
	++++c1;
	c1.display();

	/*
	基础数据类型,后++ 
	int n = 10;
	cout << n << endl;
	cout << n++ << endl;
	cout << n << endl;
	cout << n++++ << endl;	// 不允许的语法
	*/
	
	Complex c2(10, 0);
	Complex c3 = c2++;
	// c3 是用返回的临时对象初始化的
	c3.display();
	// 此时的 c2 是++后的 c2 
	c2.display();

	// 不能允许出现的语法,对返回值加 const 就可以了
	// c2++++;

	return 0;
}

评论