C++知识切片①:运算符重载之前置递增和后置递增

文章目录

在进行运算符重载之前,不妨先看看常规的前置递增和后置递增的区别:

  • 前置递增如a所示,a是先进行递增计算,然后再输出打印;
  • 后置递增如b所示,b是先进行输出打印,再进行计算

前置递增的实现

1.先写好main函数及头文件

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

int main(){
    system("pause");
    return 0;
}

2.自定义MyInteger类

由于运算符重载的目的是为了让同一运算符作用于不同类型的数据时产生不同的行为(这里的MyInteger类是我们定义的)

cpp 复制代码
class MyInteger{
    public:
    MyInteger()
    {
        m_Num = 0;
    }

    private:
    int m_Num;
};
  1. class MyInteger:定义一个名为MyInteger的类。
  2. public::这是一个访问权限声明,表示下面的成员函数是公开的,可以被类的对象和main函数中直接访问。
  3. MyInteger():这是MyInteger类的构造函数。当创建一个MyInteger对象时,这个构造函数会自动被调用,表示类的初始化。
  4. private::这是一个访问修饰符,表示下面的成员是私有的,所以外部代码不能直接访问或修改它,但类的内部函数可以。

3.重定义cout

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

class MyInteger{
    friend ostream & operator<<(ostream & cout, MyInteger myint);
    public:
    MyInteger()
    {
        m_Num = 0;
    }
    private:
    int m_Num;
};

// 重载cout
ostream & operator<<(ostream & cout, MyInteger myint)
{
    cout << myint.m_Num;
    return cout;
}

void test01()
{
    MyInteger myint;
    cout << myint << endl;
}

int main(){
    test01();
    system("pause");
    return 0;
}

这段代码定义了一个重载的输出运算符 <<,目的是将 MyInteger 对象写入到输出流中。

  1. ostream & operator<<(ostream & cout, MyInteger & myint):这是输出运算符 << 的重载函数,接受一个 ostream 引用(通常是 cout)和一个 MyInteger类型的引用作为参数,并返回一个 ostream 引用。
    • 由于C++标准库规定只能有一个cout,所以只能用引用
  2. cout << myint.m_Num;:将 myint 对象的 m_Num 成员写入到输出流 cout 中。
  3. return cout;:返回输出流 cout,以便可以连续进行额外的输出操作,如cout << myint << endl否则由于返回的是空,则只能cout << myint
  4. 为了在ostream & operator<<(......)函数中进行cout << myint.m_Num,允许访问私有成员变量m_Num,我们需要在类中声明全局函数作友元friend ostream & operator<<(ostream & cout, MyInteger & myint)

4.在类内实现前置递增

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

class MyInteger{
    friend ostream & operator<<(ostream & cout, MyInteger myint);
    public:
    MyInteger()
    {
        m_Num = 0;
    }
    // 重载前置++
    MyInteger& operator++()
    {
        m_Num++;
        return *this;//返回myint
    }
    private:
    int m_Num;
};

// 重载cout
ostream & operator<<(ostream & cout, MyInteger myint)
{
    cout << myint.m_Num;
    return cout;
}

void test01()
{
    MyInteger myint;
    cout << ++(++myint) << endl;
}

int main(){
    test01();
    system("pause");
    return 0;
}
  1. 新增的 MyInteger& operator++()函数定义了一个名为 operator++ 的成员函数(想实现运算符重载功能,都是operator 运算符的形式),该函数重载了C++中的前置递增运算符 ++

  2. MyInteger& operator++():返回类型为 MyInteger 的引用(MyInteger&),是为了对同一个数据进行递增操作

  3. return *this;:返回当前对象的引用。这里使用了解引用操作符 *this 指针,

    • this是指向myint自己的指针,this指针只允许在类内使用

    • *this对this指针解引用,即获取了该地址上存储的myint数据,

    • 返回值为引用,返回的是myint原地址上的数据(该数据是经过了myint.m_Num++操作)

    • 如果不使用MyInteger& operator++()而是MyInteger operator++(),则return的数据是重新开辟了一块新的地址空间上存储的,不能进行++(++a)这种操作

很明显,两次递增之后的myint按道理来说应该是2,但结果显示是1.原因是++myint之后的数据存储在一个新的地址空间上,而不是myint原来的地址空间上。

后置递增的实现

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

class MyInteger{
    friend ostream & operator<<(ostream & cout, MyInteger myint);
    public:
    MyInteger()
    {
        m_Num = 0;
    }
    // 重载后置++
    MyInteger operator++(int)
    {
        MyInteger temp = *this;
        m_Num++;
        return  temp;
    }
    private:
    int m_Num;
};
// 重载cout
ostream & operator<<(ostream & cout, MyInteger myint){
    cout << myint.m_Num;
    return cout;
}

void test02()
{
    MyInteger myint;
    cout << myint++ << endl;
    cout << myint << endl;
}

int main(){
    test02();
    system("pause");
    return 0;
}
  • operator++(int)中int作占位参数,告诉编译器这是后置递增, MyInteger不能返回引用,因为我们不能返回一个局部变量引用,否则在重载函数执行后,数据就被释放了,则不能访问数据

完整代码

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

class MyInteger{
    friend ostream & operator<<(ostream & cout, MyInteger myint);
    public:
    MyInteger()
    {
        m_Num = 0;
    }
    // 重载前置++
    MyInteger operator++()
    {
        m_Num++;
        return *this;//返回myint
    }
    // 重载后置++
    MyInteger operator++(int)
    {
        MyInteger temp = *this;
        m_Num++;
        return  temp;
    }
    private:
    int m_Num;
};
// 重载cout
ostream & operator<<(ostream & cout, MyInteger myint){
    cout << myint.m_Num;
    return cout;
}

void test01()
{
    MyInteger myint;
    cout << ++myint << endl;
}

void test02()
{
    MyInteger myint;
    cout << myint++ << endl;
    cout << myint << endl;
}

int main(){
    test02();
    system("pause");
    return 0;
}
相关推荐
Манго нектар25 分钟前
JavaScript for循环语句
开发语言·前端·javascript
程序猿小D34 分钟前
第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例
java·开发语言·数据库·windows·jpa
阿华的代码王国42 分钟前
【JavaEE】——文件IO的应用
开发语言·python
satan–01 小时前
R语言的下载、安装及环境配置(Rstudio&VSCode)
开发语言·windows·vscode·r语言
电饭叔1 小时前
《python语言程序设计》2018版第8章19题几何Rectangle2D类(下)-头疼的几何和数学
开发语言·python
Eternal-Student1 小时前
everyday_question dq20240731
开发语言·arm开发·php
卑微求AC2 小时前
(C语言贪吃蛇)11.贪吃蛇方向移动和刷新界面一起实现面临的问题
c语言·开发语言
程序猿小D2 小时前
第二百六十七节 JPA教程 - JPA查询AND条件示例
java·开发语言·前端·数据库·windows·python·jpa
Yvemil72 小时前
RabbitMQ 入门到精通指南
开发语言·后端·ruby
潘多编程2 小时前
Java中的状态机实现:使用Spring State Machine管理复杂状态流转
java·开发语言·spring