2025年3月21日 星期五 甲辰(龙)年 月廿 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

C++重载++和--(自增和自减运算符)

时间:03-07来源:作者:点击数:79

自增运算符++、自减运算符--都可以被重载,但是它们有前置、后置之分。

++为例,假设 obj 是一个 CDemo 类的对象,++objobj++本应该是不一样的,前者的返回值应该是 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,77,6,5,5

本程序将++重载为成员函数,将--重载为全局函数。其实都重载为成员函数更好,这里将--重载为全局函数只是为了说明可以这么做而已。

调用后置形式的重载函数时,对于那个没用的 int 类型形参,编译器自动以 0 作为实参。 如第 39 行,d++等价于d.operator++(0)

对比前置++和后置++运算符的重载可以发现,后置++运算符的执行效率比前置的低。因为后置方式的重载函数中要多生成一个局部对象 tmp(第21行),而对象的生成会引发构造函数调用,需要耗费时间。同理,后置--运算符的执行效率也比前置的低。

前置++运算符的返回值类型是 CDemo &,而后置++运算符的返回值类型是 CDemo,这是因为运算符重载最好保持原运算符的用法。C++ 固有的前置++运算符的返回值本来就是操作数的引用,而后置++运算符的返回值则是操作数值修改前的复制品。例如:

  • int a = 5;
  • (++a) = 2;

上面两条语句执行后,a 的值是 2,因为 ++a 的返回值是 a 的引用。而

  • (a++) = 2;

这条语句是非法的,因为 a++ 的返回值不是引用,不能作为左值。

--运算符的返回值类型的设定和++运算符一样。

在有的编译器(如Visual Studio)中,如果没有后置形式的重载,则后置形式的自增或自减表达式也被当作前置形式处理。而在有的编译器(如Dev C++)中,不进行后置形式的重载,则后置形式的表达式就会编译出错。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门