c++递增运算符重载:通过重载递增运算符,实现自定义数据类型递增
#include<iostream>
using namespace std;
class Myinteger
{
public:
Myinteger()
{
m_num = 0;
}
private:
int m_num;
};
void test01()
{
Myinteger myint;
cout << ++myint << endl;
cout << myint << endl;
}
int main(){
test01();
return 0;
}
先定义一个Myinteger类,然后在test01函数创建一个对象myint,我们现在想要实现一个让myint的m_num递增的功能。如果直接写cout << ++myint << endl;编译器是无法识别的,因为我们需要进行递增运算符重载。而递增运算符分两种:前置递增和后置递增。前置递增是先让变量+1再进行表达式的运算,后置递增是先进行表达式的计算,再让变量+1。
我们先实现前置递增:
class Myinteger
{
public:
Myinteger()
{
m_num = 0;
}
//重载前置++运算符
Myinteger& operator++()
{
//先进行++运算
m_num++;
//再将自身返回
return * this;
}
private:
int m_num;
};
void test01()
{
Myinteger myint;
cout << ++myint << endl;
cout << myint << endl;
}
int main(){
test01();
return 0;
}
重载递增运算符写在成员函数里,因此我们要实现类的对象的本体自增,只需调用成员函数即可,无需在形参列表里传入形参。代码实现思路是,先创建对象myint,然后myint调用有参构造函数将myint的m_num设置初始值为0。然后再调用重载递增运算符成员函数,将myint的m_num实现+1的效果,然后再将myint的数据通过this指针解引用进行返回。
此时运算符要输出++myint,但是编译器是无法识别的。我们还要做左移运算符重载的操作。
ostream & operator<<(ostream &cout, Myinteger myint)
{
cout << myint.m_num;
return cout;
}
在重载左移运算符函数中,要访问对象myint中的m_num数据,而该数据在上面定义时写到了私有权限下,因此需要用到友元,需要在类中声明,使得operator<<()函数可以访问到类中私有权限的内容。
class Myinteger
{
friend ostream & operator<<(ostream &cout, Myinteger myint);
public:
Myinteger()
{
m_num = 0;
}
此时编译器就可以识别cout << ++myint;并进行输出了。
//重载前置++运算符
Myinteger& operator++()
{
//先进行++运算
m_num++;
//再将自身返回
return * this;
}
为什么重载前置运算符函数的返回值是引用返回?
void test01()
{
Myinteger myint;
cout << ++(++(++myint)) << endl;
cout << myint << endl;
}
如果使用值返回方式,当执行输出++(++(++myint))时可以得到正确的结果3。因为第一次调用重载递增运算符函数将myint本体自身加1,后返回myint副本数据记为myint1,然后执行第二个++时则是由myint1调用重载递增运算符函数进行对myint1自身+1,然后返回myint1副本数据记为myint2,第三次同理,对myint2+1后再返回myint2副本数据记为myint3,这时输出的值就是myint3的值3,达到我们想要的结果。但我们可以发现,前置递增是先自身+1再进行表达式的计算,所以当++(++(++myint))输出为3时myint也应该为3,但此时输出myint结果为1。就是因为我们使用了值返回的方式,一直在创造副本数据,这个递增的效果也一直作用在了副本数据上,而本体数据在第一次进行+1后就没有继续进行累加。所以我们这里要使用引用传递的方式,每一次返回的都是本体数据,再由本体数据进行调用前置运算符重载函数完成对自身的递增。
后置递增:
Myinteger operator++(int)
{
//先记录结果
Myinteger temp = * this;
//后递增
m_num++;
//最后将记录结果做返回
return temp;
}
后置递增是先进行表达式的计算,在对自身+1。因此实现思路是先定义一个临时变量通过对this指针解引用来记录当前传入的数据,然后对数据进行+1的效果,最后再将我们定义的临时变量返回。这样就实现了后置递增。这里为了区分前置递增和后置递增两个函数,我们会在后置递增形参列表写上一个int,这是一个占位参数,让编译器可以识别前置递增和后置递增两个不同的函数。
ostream & operator<<(ostream &cout, Myinteger myint)
{
cout << myint.m_num;
return cout;
}
为什么形参列表中使用值传递而不是引用传递?
因为在后置递增运算符重载我们是以值方式进行返回的,所以返回的是拷贝的副本数据而不是本体数据,如果这里用引用传递调用左移运算符,那么后置递增运算符就会因为无法向形参列表传入本体数据而无法调用左移运算符函数,发生错误。
下面是全代码:
#include<iostream>
using namespace std;
//自定义整型
class Myinteger
{
friend ostream & operator<<(ostream &cout, Myinteger myint);
public:
Myinteger()
{
m_num = 0;
}
//重载前置++运算符
Myinteger& operator++()
{
//先进行++运算
m_num++;
//再将自身返回
return * this;
}
//重载后置++运算符
Myinteger operator++(int)
{
//先记录结果
Myinteger temp = * this;
//后递增
m_num++;
//最后将记录结果做返回
return temp;
}
private:
int m_num;
};
ostream & operator<<(ostream &cout, Myinteger myint)
{
cout << myint.m_num;
return cout;
}
void test01()
{
Myinteger myint;
cout << ++(++(++myint)) << endl;
cout << myint << endl;
}
void test02()
{
Myinteger myint;
cout << myint++ << endl;
cout << myint << endl;
}
int main(){
test01();
test02();
return 0;
}
若有错误,接受批评,欢迎指正!