C++重载++和--(自增和自减运算符)
自增运算符
以
那么不论
为了解决这个问题,C++ 规定,在重载
程序运行结果:
5,6,7,7
7,6,5,5
本程序将
调用后置形式的重载函数时,对于那个没用的 int 类型形参,编译器自动以 0 作为实参。 如第 39 行,
对比前置
前置
上面两条语句执行后,a 的值是 2,因为 ++a 的返回值是 a 的引用。而
这条语句是非法的,因为 a++ 的返回值不是引用,不能作为左值。
在有的编译器(如Visual Studio)中,如果没有后置形式的重载,则后置形式的自增或自减表达式也被当作前置形式处理。而在有的编译器(如Dev C++)中,不进行后置形式的重载,则后置形式的表达式就会编译出错。
++
、自减运算符--
都可以被重载,但是它们有前置、后置之分。以
++
为例,假设 obj 是一个 CDemo 类的对象,++obj
和obj++
本应该是不一样的,前者的返回值应该是 obj 被修改后的值,而后者的返回值应该是 obj 被修改前的值。如果如下重载++
运算符:
- CDemo & CDemo::operator ++ ()
- {
- //...
- return * this;
- }
obj++
还是++obj
,都等价于obj.operator++()
无法体现出差别。为了解决这个问题,C++ 规定,在重载
++
或--
时,允许写一个增加了无用 int 类型形参的版本,编译器处理++
或--
前置的表达式时,调用参数个数正常的重载函数;处理后置表达式时,调用多出一个参数的重载函数。来看下面的例子:
- #include <iostream>
- using namespace std;
- class CDemo {
- private:
- int n;
- public:
- CDemo(int i=0):n(i) { }
- CDemo & operator++(); //用于前置形式
- CDemo operator++( int ); //用于后置形式
- operator int ( ) { return n; }
- friend CDemo & operator--(CDemo & );
- friend CDemo operator--(CDemo & ,int);
- };
- CDemo & CDemo::operator++()
- {//前置 ++
- n ++;
- return * this;
- }
- CDemo CDemo::operator++(int k )
- { //后置 ++
- CDemo tmp(*this); //记录修改前的对象
- n++;
- return tmp; //返回修改前的对象
- }
- CDemo & operator--(CDemo & d)
- {//前置--
- d.n--;
- return d;
- }
- CDemo operator--(CDemo & d,int)
- {//后置--
- CDemo tmp(d);
- d.n --;
- return tmp;
- }
- int main()
- {
- CDemo d(5);
- cout << (d++ ) << ","; //等价于 d.operator++(0);
- cout << d << ",";
- cout << (++d) << ","; //等价于 d.operator++();
- cout << d << endl;
- cout << (d-- ) << ","; //等价于 operator-(d,0);
- cout << d << ",";
- cout << (--d) << ","; //等价于 operator-(d);
- cout << d << endl;
- return 0;
- }
5,6,7,7
7,6,5,5
本程序将
++
重载为成员函数,将--
重载为全局函数。其实都重载为成员函数更好,这里将--
重载为全局函数只是为了说明可以这么做而已。调用后置形式的重载函数时,对于那个没用的 int 类型形参,编译器自动以 0 作为实参。 如第 39 行,
d++
等价于d.operator++(0)
。对比前置
++
和后置++
运算符的重载可以发现,后置++
运算符的执行效率比前置的低。因为后置方式的重载函数中要多生成一个局部对象 tmp(第21行),而对象的生成会引发构造函数调用,需要耗费时间。同理,后置--
运算符的执行效率也比前置的低。前置
++
运算符的返回值类型是 CDemo &,而后置++
运算符的返回值类型是 CDemo,这是因为运算符重载最好保持原运算符的用法。C++ 固有的前置++
运算符的返回值本来就是操作数的引用,而后置++
运算符的返回值则是操作数值修改前的复制品。例如:
- int a = 5;
- (++a) = 2;
- (a++) = 2;
--
运算符的返回值类型的设定和++
运算符一样。在有的编译器(如Visual Studio)中,如果没有后置形式的重载,则后置形式的自增或自减表达式也被当作前置形式处理。而在有的编译器(如Dev C++)中,不进行后置形式的重载,则后置形式的表达式就会编译出错。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算