CPP学习之——重载自加运算符的执行次序(18.20)

一 概述

本节演示自加运算符的执行次数,给类A增加两个重载函数,一个是前置自加运算符函数,一个是后置自加运算符函数。重载的目的是使类A的对象也可以像变量那样执行前置和后置自加操作。

二 前置自加和后置自加分析

2.1 分析

  • 接下来给两个函数增加功能,前置自加就是先自加,然后返回自加后的值,这样我们将rx自加后,再将rx返回即可。
  • 后置自加与其相反,需要先将rx的值返回,然后再将rx自加,为了实现这一点,我们需要一个变量保存rx的值,将rx自加后,再返回该变量的值即可。

2.2 代码

1
2
int operator++(){cout<<"++i=";rx++;return rx;}
int operator++(int){cout<<"i++=";int i=rx;rx++;return i;}

三 示例演示及结果输出

3.1 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
using namespace std;
class A {
public:
A(int x){rx = x;}
friend ostream&operator<<(ostream&s,A&a)
{
s<<a.rx;
return s;
}
int operator++(){cout<<"++i\n";rx++;return rx;}
int operator++(int){cout<<"i++\n";int i=rx;rx++;return i;}
private:
int rx;
};

int main()
{
A a(3);
cout<<++a<<a++<<endl;
//cout<<++a<<endl;
//cout<<a++<<endl;
return 0;
}

3.2 输出结果

1
2
3
i++
++i
53

后置自加运算符函数operator++(int)调用在线,前置自加运算符函数operator++()调用在后,输出的数值更加令人迷糊,先输出5,后输出3.这是为什么?

3.3 原因分析

  • 这是因为当给一个函数传进来的参数不是一个简单的变量,而是一个有运算的表达式时,可能发生先把所有的表达式求值,在进行参数压栈的情况;也有可能是一边求值一边压栈,求出一个压一个,不同的编译器做法不尽相同
  • 在VC6.0编译器中,首先将参数的值求出,然后再压栈,由于在无括号的情况下,求参数的值的顺序是从右至左,因此首先求最右侧的参数a++,这会调用后置自加operator++(int)函数,并在自加前返回i的值,因此a++的值为3,紧接着再求左边的++a,这时会调用前置自加运算符函数,并将rx加1后返回rx的值。由于前面已经将rx加了1,因此再加则为5.