C++面向对象-14-递增运算符的重载

接着来学习递增运算符的重载,有一个变量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;
}

运行结果

C++面向对象-14-递增运算符的重载_第1张图片

总结:

前置递增:先让变量递增,在计算表达式值。

后置递增:先做表达式运算,再让变量递增。

 

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;
}

重点都在代码注释里。有了这个递增重载的思路,要写一个递减那就很简单,改一下符号就可以。

你可能感兴趣的:(C++学习笔记,递增运算符重载)