接着来学习递增运算符的重载,有一个变量i, i++ 这个++符号就是递增运算符。前面学习了几个运算符重载,需要明白的是,对于基本数据类型的运算,我们是不可以进行重载,例如两个int类型的数的加减乘除都不可以进行运算符的重载。我们需要使用运算符的重载是解决一些自定义的数据类型的时候。
1.基本整形数据的前置和后置递增
我们先来回顾一下整形变量前置递增和后置递增的规律。
#include
using namespace std;
int main()
{
int a = 10;
int b = 10;
//前置递增
cout << "++b = " << ++b << endl; // 11
cout << "b = " << b << endl; //11
//后置递增
cout << "a++ = " << a++ << endl; // 10
cout << "a = " << a << endl; // 11
system("pause");
return 0;
}
运行结果
总结:
前置递增:先让变量递增,在计算表达式值。
后置递增:先做表达式运算,再让变量递增。
2.需求
我们需要支持自定义一个Integer类,里面维护一个Int数据,支持使用类对象的名称进行前置递增和后置递增。
#include
using namespace std;
class MyInteger
{
private:
int m_Number;
public:
MyInteger()
{
m_Number = 0;
}
};
void test01()
{
MyInteger mi;
cout << mi << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
需求就是我们只输入对象名称,或者mi++ 来支持输出,这个就是我们重载递增运算符的需求(上面第19行代码会报错)。
3.前置递增重载实现
这里我们是cout << 对象支持链式编程,所以我们这里需要用到前面一篇的左移运算符重载。为了实现cout在左边,我们重载都选择全局函数的方式。
先实现左移,能够输出自定义类的属性值,代码如下
#include
using namespace std;
class MyInteger
{
friend ostream & operator<<(ostream &out, MyInteger mi);
private:
int m_Number;
public:
MyInteger()
{
m_Number = 0;
}
};
ostream & operator<<(ostream &out, MyInteger mi)
{
out << mi.m_Number;
return out;
}
void test01()
{
MyInteger mi;
cout << mi << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
输出值是0,接下来,考虑如何写前置递增的运算符重载。
前置递增重载实现
#include
using namespace std;
class MyInteger
{
friend ostream & operator<<(ostream &out, MyInteger mi);
private:
int m_Number;
public:
MyInteger()
{
m_Number = 0;
}
//重载前置++运算符
MyInteger& operator++()
{
// 先进行++运算
m_Number++;
// 在将自身返回,返回一个引用
return *this;
}
};
ostream & operator<<(ostream &out, MyInteger mi)
{
out << mi.m_Number;
return out;
}
void test01()
{
MyInteger mi;
cout << ++mi << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
这里来分析这个重载函数
//重载前置++运算符
MyInteger& operator++()
{
// 先进行++运算
m_Number++;
// 在将自身返回,返回一个引用
return *this;
}
这里为什么要返回一个引用,而不是直接返回值
//重载前置++运算符
MyInteger operator++()
{
// 先进行++运算
m_Number++;
// 在将自身返回,返回一个引用
return *this;
}
下面我们改成返回值的方式,来测试一段代码
#include
using namespace std;
class MyInteger
{
friend ostream & operator<<(ostream &out, MyInteger mi);
private:
int m_Number;
public:
MyInteger()
{
m_Number = 0;
}
//重载前置++运算符
MyInteger operator++()
{
// 先进行++运算
m_Number++;
// 在将自身返回,返回一个引用
return *this;
}
};
ostream & operator<<(ostream &out, MyInteger mi)
{
out << mi.m_Number;
return out;
}
void test01()
{
MyInteger mi;
cout << ++(++mi ) << endl;
cout << mi << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
看上面代码34 35行,34行连续对一个对象做了两次自增,打印结果应该是2,运行上面代码打印对象mi的结果却是1,这个前置递增效果,和文章中开头演示的int数据类型前置递增效果不一致。所以回到重载函数,这里就需要返回一个引用,而不是返回值。
4.后置递增实现
#include
using namespace std;
class MyInteger
{
friend ostream & operator<<(ostream &out, MyInteger mi);
private:
int m_Number;
public:
MyInteger()
{
m_Number = 0;
}
//重载前置++运算符
MyInteger& operator++()
{
// 先进行++运算
m_Number++;
// 在将自身返回,返回一个引用
return *this;
}
//重载后置++运算符
// 参数int是占位参数,用来区分前置还是后置,固定写法
MyInteger operator++(int)
{
//先记录当时结果
MyInteger temp = *this;
//然后变量递增
m_Number++;
//最后返回当时记录的结果
return temp;
}
};
ostream & operator<<(ostream &out, MyInteger mi)
{
out << mi.m_Number;
return out;
}
void test01()
{
MyInteger mi;
cout << mi++ << endl;
cout << mi << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
重点都在代码注释里。有了这个递增重载的思路,要写一个递减那就很简单,改一下符号就可以。