CPP 核心编程4-重载递增运算符
创始人
2024-03-20 02:58:24
0

在这里插入图片描述
在这里插入图片描述

#include "iostream"using namespace std;//递增运算符重载
//自定义整型
class MyInteger {friend ostream &operator<<(ostream &cout, MyInteger mi);public:MyInteger() {m_Num = 0;}//重置前置++运算符  返回引用是为了对同一个数进行操作MyInteger &operator++() {//这里不能返回值MyInteger 必须返回MyInteger&  因为操作的需要是都一个对象,返回值就是拷贝了//先进行++运算m_Num++;//再将自身作返回return *this;}//重置后置++运算符private:int m_Num;
};//重载左移运算符
ostream &operator<<(ostream &cout, MyInteger mi) {cout << mi.m_Num;return cout;
}void test() {MyInteger mi;cout << ++(++mi) << endl;//C++里面原生的前置递增可以链式调用,后置递增不可以链式调用
}int main() {
//    test();//C++里面原生的前置递增可以链式调用,后置递增不可以链式调用int a = 0;++(++a);cout << a << endl;//输出2return 0;
}
2

后置递增
C++里面后置++是不能链式调用的

#include "iostream"using namespace std;//递增运算符重载
//自定义整型
class MyInteger {friend ostream &operator<<(ostream &cout, MyInteger mi);public:MyInteger() {m_Num = 0;}//重置前置++运算符  返回引用是为了对同一个数进行操作MyInteger &operator++() {//这里不能返回值MyInteger 必须返回MyInteger&  因为操作的需要是都一个对象,返回值就是拷贝了//先进行++运算m_Num++;//再将自身作返回return *this;}//重置后置++运算符   !!!!!!之前学习的占位符终于找到用武之地了//返回值用const修饰,他能防止一些问题,例如: (p++)++const MyInteger operator++(int) {//int 代表占位参数,可以用于区分前置和后置递增,这里只能是int,double等不好使MyInteger temp = *this;m_Num++;return temp;}private:int m_Num;
};//重载左移运算符
ostream &operator<<(ostream &cout, MyInteger mi) {cout << mi.m_Num;return cout;
}void test() {MyInteger mi;
//    cout << ++(++mi) << endl;cout << mi++ << endl;//输出0   //返回值用const修饰,他能防止一些问题,例如: (p++)++cout << mi << endl;//输出1
}int main() {test();return 0;
}
0
1

递增运算符分为前置递增和后置递增。这两个分开来说吧。
前置递增。
需要创建一个名字叫做 人 的类,这个类中有一个 年龄 属性,且默认值为0,然后类外重载左移运算符方便打印输出。我们对人类的对象进行递增操作就是想让年龄增加。如下:

#include 
using namespace std;class Person
{
public:
int age = 0;
Person& operator++()//**1**
{
age += 1;
return *this;
}
};
ostream& operator<<(ostream& cout, const Person &p)
{
cout << p.age;
return cout;
}
void test1()
{
Person p;
cout << "++p = " << ++p << endl;
cout << "++(++p) = " << ++(++p) << endl;
cout << "p = " << p << endl;
}
int main()
{
test1();
system("pause");
return 0;
}

第一个问题 :返回值为什么是引用?
答案:因为前置递增运算符可以这样使用:++(++p)。即进行两次连续的递增操作。若返回值为一个对象,则会产生一个匿名对象,之后++操作是对匿名独对象进行++操作。结果如下:
第二个问题 :为什么这是前置递增,不应该是后置递增吗?
首先解释一下问题,还是举个例子吧。
加运算符在类内实现重载的写法:Person operator+(Person &p);
当你调用的时候,如:p1 + p2,其本质调用是 p1.operator+(p2); 。你会发现,是 +号前面的对象调用函数,加号后面的对象是参数 。所以,当我们调用Person& operator++();的时候,是不是应该写 p1++??
答案:(个人推测)可能和后置递增有关。为了区分前置和后置。

在这里插入图片描述

后置递增。
第一个问题 :是后置递增类内重载的写法遇到的问题:
返回值和参数都是啥??想这样写??

Person operator++();
Person& operator++();
Person operator++(Person& p);
....

想了好久,也没想出来该怎么写。
答案:const Person operator++(int)
其中int的作用是占位符,为了和前置递增区分开来,而且只能写int,写double、float等都是不行的。因为没有这个占位参数的话,该函数与前置递增就只有返回值不同了,而返回值是不可以作为函数重载的条件的。
至于返回值的为什么是Person话,而且还用const修饰,在下一个问题中说明。
第二个问题 具体是怎样实现的,毕竟后置递增和前置递增还是有区别的。
答案:

const Person operator++(int)
{
Person p = *this;
age += 1;
return p;
}

首先创建一个临时的对象,用来保存当前值,因为该函数最后返回的不是递增后的结果,而是递增之前的值。
然后,属性加一,完成递增操作。
最后,返回临时对象
注意1: 此时的temp是一个临时对象,该函数运行结束后就会被编译器回收,所以我们直接返回temp的引用。我们需要进行值返回,值返回的话会调用拷贝构造函数重新创建一个对象。
注意2: 返回值用const修饰,他能防止一些问题,例如: (p++)++ 。我们可以做一个小测试。

int p = 0;
cout << "(p++)++ = " << (p++)++ << endl;
cout << "p = " << p << endl;

我们预想的结果可能是输出:(p++)++ = 1 p = 2
但实际结果是这样的:
报错了,原因是++需要可修改的左值。从结果我们可以知道,表达式p++的结果是不允许被修改的,所以我们后置递增的返回值是const类型的。
那么为什么会这样呢?
同样举个例子:
在这里插入图片描述

int p;
cout << "p = " << p << endl;
cout << "p++ = " << p++ << endl;
cout << "p = " << p << endl;

运行结果如下:
我们输出 p++ 的结果是0,这个0是哪里来的呢??是变量p中存储的吗??并不是,此时p中存储的值已经被改变了,这个0是产生的一个临时值。这个临时值在内存中的位置是未知的,我们无法对其进行修改。
所以,当我们 (p++)++ 这样使用后置递增运算符的时候,相当于尝试修改临时变量的值,这是不被允许的。
所以,我们重载递增操作符的返回值要用const来修饰。
在这里插入图片描述

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...