本文主要讨论下C++中++操作符的重载问题,为什么专门把++提出来介绍下它的重载?不知道大家有没有思考过一个问题?一般情况下我们重载一个操作符时,只要定义一个重载函数"operator操作符()"即可,那么重载++和--这两个操作符怎么办,要知道++是要分为前++和后++的,如果单纯重载++操作符,怎么区分前++和后++?
C++中为了解决这个问题,采用了将后++定义成一个带有int型参数的形式,也就是说:
前++的重载函数:Integer&operator++ ();
后++的重载函数:constInteger operator++(int);
Integer使我们自定义的类,也就是需要为其实现重载函数的类,后++的重载形式利用了哑元,因为我们不会用到这个参数。好,列出本次试验的源代码:
#include<iostream>
using namespace std;
class Integer
{
private:
int m_i;
public:
Integer(int i):m_i(i){}
void print() const
{
cout<<m_i<<endl;
}
Integer& operator++()
{
++(this->m_i);
return *this;
}
const Integer operator++(int)
{
Integer old=*this;
++(this->m_i);
return old;
}
};
int main()
{
Integer i1(10),i2(100);
(++i1).print();
(i2++).print();
return 0;
}
为了验证后++被编译器翻译成带参的重载函数的说法,我们先不着急运行,而是用g++ -S 选项生成cpp文件的汇编文件:
[Hyman@Hyman-PC Integer]$ g++ -S oper++.cpp
[Hyman@Hyman-PC Integer]$ vim oper++.s
[Hyman@Hyman-PC Integer]$ vim oper++.s
结果如下:
请注意图中红色圈出部分,分别对应main函数中调用函数过程,依次是:
1、 调用Integer的带参构造函数Integer(inti)构造i1;
2、 调用Integer的带参构造函数Integer(inti)构造i2;
3、 调用Integer的重载前++的函数operator++(),请注意编译器将operator++()的换名,换成了_ZN7IntegerppEv,最后一个字符v表示函数的参数为void,也就是我们重载的operator++()函数。
4、 调用Integer的print()函数。
5、 调用Integer的重载后++的函数operator++(int),本次编译器将operator++(int)的换名,换成了_ZN7IntegerppEi,最后一个字符i表示函数的参数为int,这也就足以证明了编译器直接将后++的重载函数翻译成了带int参数的形式。
6、 调用Integer的print()函数。
最后,我们再来看下运行结果:
[Hyman@Hyman-PC Integer]$ g++ oper++.cpp
[Hyman@Hyman-PC Integer]$ ./a.out
11
100
结果正确,重载完成。