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;
}
相关推荐
艾莉丝努力练剑10 分钟前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
还债大湿兄2 小时前
《C++内存泄漏8大战场:Qt/MFC实战详解 + 面试高频陷阱破解》
c++·qt·mfc
倔强青铜34 小时前
苦练Python第18天:Python异常处理锦囊
开发语言·python
u_topian5 小时前
【个人笔记】Qt使用的一些易错问题
开发语言·笔记·qt
珊瑚里的鱼5 小时前
LeetCode 692题解 | 前K个高频单词
开发语言·c++·算法·leetcode·职场和发展·学习方法
AI+程序员在路上5 小时前
QTextCodec的功能及其在Qt5及Qt6中的演变
开发语言·c++·qt
xingshanchang5 小时前
Matlab的命令行窗口内容的记录-利用diary记录日志/保存命令窗口输出
开发语言·matlab
Risehuxyc5 小时前
C++卸载了会影响电脑正常使用吗?解析C++运行库的作用与卸载后果
开发语言·c++
AI视觉网奇5 小时前
git 访问 github
运维·开发语言·docker
不知道叫什么呀6 小时前
【C】vector和array的区别
java·c语言·开发语言·aigc