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;
}
相关推荐
Bayi·31 分钟前
前端面试场景题
开发语言·前端·javascript
碎梦归途32 分钟前
23种设计模式-结构型模式之享元模式(Java版本)
java·开发语言·jvm·设计模式·享元模式
明月看潮生34 分钟前
青少年编程与数学 02-018 C++数据结构与算法 06课题、树
数据结构·c++·算法·青少年编程·编程与数学
小指纹37 分钟前
动态规划(一)【背包】
c++·算法·动态规划
Xiaoyu Wang37 分钟前
Go协程的调用与原理
开发语言·后端·golang
bigear_码农1 小时前
python异步协程async调用过程图解
开发语言·python·线程·进程·协程
zhaoyqcsdn1 小时前
抽象工厂模式及其在自动驾驶中的应用举例(c++代码实现)
c++·经验分享·笔记·设计模式
天若有情6732 小时前
用 C++ 模拟 Axios 的 then 方法处理异步网络请求
网络·c++·php
知识分享小能手2 小时前
JavaScript学习教程,从入门到精通,Ajax与Node.js Web服务器开发全面指南(24)
开发语言·前端·javascript·学习·ajax·node.js·html5
凌叁儿2 小时前
Python 的 datetime 模块使用详解
开发语言·python