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;
}
相关推荐
软件黑马王子几秒前
C#初级教程(4)——流程控制:从基础到实践
开发语言·c#
闲猫3 分钟前
go orm GORM
开发语言·后端·golang
黑不溜秋的1 小时前
C++ 设计模式 - 策略模式
c++·设计模式·策略模式
李白同学2 小时前
【C语言】结构体内存对齐问题
c语言·开发语言
黑子哥呢?3 小时前
安装Bash completion解决tab不能补全问题
开发语言·bash
青龙小码农3 小时前
yum报错:bash: /usr/bin/yum: /usr/bin/python: 坏的解释器:没有那个文件或目录
开发语言·python·bash·liunx
大数据追光猿3 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!3 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
柠石榴3 小时前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
王老师青少年编程3 小时前
【GESP C++八级考试考点详细解读】
数据结构·c++·算法·gesp·csp·信奥赛