Bootstrap

C++:重载++与--操作符


C与C++中 ++ 与 - - 的区别

  • 在C语言中,前置和后置++,- -都不能作为左值

  • 在C++中,前置的++和- -可以作为左值,(从下面的重载运算符中也可以看出,它们返回的是引用)

  • C++类似的提升还有三目运算符?:,在c中也不可以做左值,但c++中可以。

重载++、- -操作符原理:

自增运算符++、自减运算符- -都可以被重载,但是它们有前置、后置之分。 但是不论a++还是++a,都等价于a.operator++()无法体现出差别。

为了解决这个问题,C++ 规定,在重载++或- -时,允许写一个增加了无用 int 类型形参的版本

编译器处理++或- -前置的表达式时,调用参数个数正常的重载函数;处理后置表达式时,调用多出一个参数的重载函数。

图解++操作符,前置与后置的区别

在这里插入图片描述

代码示例:
#include <iostream>
using namespace std;

class Test{
	int m_a;
public:
	Test(int a = 0) :
		m_a(a)
	{

	}

	//前置++
	Test& operator ++ ()
	{
		m_a++;
		return *this;
	}

	//后置++(Test 后不跟 & 是因为返回值不能被赋值)
	Test operator ++ (int)
	{
		Test tmp = *this;
		m_a++;
		return tmp;
	}

	//前置--
	Test& operator -- ()
	{
		m_a--;
		return *this;
	}

	//后置--
	Test operator -- (int)
	{
		Test tmp = *this;
		m_a--;
		return tmp;
	}

	friend ostream & operator << (ostream & os, Test & t);
};

ostream & operator << (ostream & os, Test & t)
{
	os << t.m_a;
	return os;
}

int testop()
{
	Test t(7);

	// 隐式调用
	cout << t++ << endl;	// 7
	cout << t << endl;		// 8
	cout << --t << endl;	// 7
	cout << t << endl;		// 7
	
	// 显示调用(调用后置版本,经测试,不用0也行,只要可以转换成int的任意数。)
	cout << t.operator++(0) << endl;	// 7
	cout << t << endl;	// 8

	return 0;
}

要点总结:
  1. 对比前置++和后置++运算符的重载可以发现,后置++运算符的执行效率比前置的低。因为后置方式的重载函数中要多生成一个局部对象 tmp,而对象的生成会引发构造函数调用,需要耗费时间。同理,后置- -运算符的执行效率也比前置的低。
  2. 前置++运算符的返回值类型是 Test&,而后置++运算符的返回值类型是 Test,这是因为运算符重载最好保持原运算符的用法。C++ 固有的前置++运算符的返回值本来就是操作数的引用,而后置++运算符的返回值则是操作数值修改前的复制品。
  3. 在前的重载不需要参数,在后的重载需要一个象征性的 int 参数。

知识点习题

  1. 在重载一个运算符为成员函数时,其参数表中没有任何参数,这说明该运算符是 ( )。

A. 无操作数的运算符
B. 二元运算符
C. 前缀一元运算符
D. 后缀一元运算符

正确答案: C


如有不同见解,欢迎留言讨论!!!

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;