运算符重载

一.运算符重载基本规则

1.运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。

2.一般来讲,重载的功能应当与原有功能相似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。

3.运算符的重载形式有两种,分别是重载为类的非静态成员和重载为非成员函数,下面我们也将从两种下手开始讨论。

它们的一般语法形式为:

返回类型 operator 运算符(形参表)
{

函数体

}

注:返回类型指定了重载运算符的返回类型,也就是运算结果类型。

二.加减法重载

说明:重载为类的成员函数时,第一个操作数会被作为函数调用的目的对象,因此无法出现在参数表中。即oprd1 B oprd2,其中oprd1为A类的对象,则应当把B重载为A类的成员函数,该函数只有一个形参,形参的类型是oprd2所属的类型,即oprd1 B oprd2相当于oprd1.operator B(oprd2)

(一).加减法重载为成员函数


#include "pch.h"
#include <iostream> using namespace std; class Complex
{
public:
Complex(double r=0.0,double i=0.0):real(r),imag(i){}
Complex operator+(const Complex &c2)const;
Complex operator-(const Complex &c2)const;//用对象作为参数时,用引用或者传地址,一般用引用
void display()const
{
cout << "(" << real << "," << imag << ")" << endl;
}
private:
double imag, real;//复数的虚部和实部
}; Complex Complex::operator+(const Complex &c2)const
{
return Complex(real + c2.real, imag + c2.imag);//创建了一个临时无名对象作为返回值
} Complex Complex::operator-(const Complex &c2)const
{
return Complex(real - c2.real, imag - c2.imag);//创建了一个临时无名对象作为返回值
} int main()
{
Complex c1(5, 4), c2(2, 3), c3;
cout << "c1="; c1.display();
cout << "c2="; c2.display();
c3 = c1 + c2;
cout << "c3=c1+c2="; c3.display();
c3 = c1 - c2;
cout << "c3=c1-c2="; c3.display();
return 0;
}

运行结果:

  • 修改1:由上面写的说明,我们来对说明进行证明,我们修改代码如图

我们运行可以正常运行,证明了我们上面的说明。

  • 修改2:我们定义一个新的Complex类型的c,对它进行以下操作

注:这里我们看到整数5加到了原来c1的5上,可能有的人会想为什么不在c1的4上也加上,这里我们需要理解一下复数(a+bi)+(c+di)=(a+c)+(b+d)i。

当我们加上5的时候相当于让实部为5,让虚部为0了即让d为0了。

  • 修改3:

我们发现也是正确的,那如果我们把它写成c=5+c1又会不会对呢?

  • 修改4:

我们发现程序报错,说明这样是不对的,那我们怎样解决它呢?这里就需要我们把运算符重载为非成员函数了。那这又是为什么呢?

(二).加减法重载为非成员函数


#include "pch.h"
#include <iostream> using namespace std; class Complex
{
public:
Complex(double r=0.0,double i=0.0):real(r),imag(i){}
friend Complex operator+(const Complex &c1,const Complex &c2);
friend Complex operator-(const Complex &c1,const Complex &c2);//用对象作为参数时,用引用或者传地址,一般用引用
void display()
{
cout << "(" << real << "," << imag << ")" << endl;
}
private:
double imag, real;
}; Complex operator+(const Complex &c1, const Complex &c2)
{
return Complex(c1.real + c2.real, c1.imag + c2.imag);//创建了一个临时无名对象作为返回值
} Complex operator-(const Complex &c1, const Complex &c2)
{
return Complex(c1.real - c2.real, c1.imag - c2.imag);//创建了一个临时无名对象作为返回值
} int main()
{
Complex c1(5, 4), c2(2, 3), c3,c;
cout << "c1="; c1.display();
cout << "c2="; c2.display(); c3 = c1 + c2;
cout << "c3=c1+c2="; c3.display();
c3 = c1 - c2;
cout << "c3=c1-c2="; c3.display(); c =5+ c1 ;
cout << "c=c1+5="; c.display(); return 0;
}

运行截图:

我们注意看这里就实现了c=5+c1。

那我们思考为什么以非成员函数形式重载,就可以实现c=5+c1呢?

(教材的315页对此进行了详细解释)因为Comlpex的构造函数使得实数可以隐含转换为Complex类型,而以成员函数重载的时候,左操作数是调用成员函数的目的对象,它不会被隐含转化,只有右操作数是函数的参数,可以隐含转化为Complex类型。

三.“++”的重载

(一)“++”的重载为成员函数

#include "pch.h"
#include <iostream> using namespace std; class Complex
{
public:
Complex(double r=0.0,double i=0.0):real(r),imag(i){}
Complex &operator++();
Complex operator++(int);//后++
void display()
{
cout << "(" << real << "," << imag << ")" << endl;
}
private:
double imag, real;
}; Complex &Complex::operator++()
{
imag++;
real++;//先++
return *this;
} Complex Complex::operator++(int)
{
Complex a = *this;//this指向的原来的对象,先把自己的值弄出来,在对自己++
++(*this);
return a;
} int main()
{
Complex a(1, 2),b,d;
a.display(); b = ++a;
cout << "++a="; b.display();
d = a++;
cout << "a++="; d.display(); cout << "a++后"; a.display(); return 0;
}

运行截图:

这里我们注意看先++和后++的区别,在代码的最后我们也可以看到,后++的实现。

(二)“++”的重载为非成员函数


#include "pch.h"
#include <iostream> using namespace std; class Complex
{
public:
Complex(double r=0.0,double i=0.0):real(r),imag(i){} friend Complex operator++(Complex &c);//前++
friend Complex operator++(Complex &c,int);//后++ void display()
{
cout << "(" << real << "," << imag << ")" << endl;
}
private:
double imag, real;
}; Complex operator++(Complex &c)//前++
{
c.imag++;
c.real++;
return c;
} Complex operator++(Complex &c,int)//后++
{
Complex a = c;
++c;
return a;
} int main()
{
Complex a(1, 2),b,d;
a.display(); b = ++a;
cout << "++a="; b.display();
d = a++;
cout << "a++="; d.display(); cout << "a++后"; a.display(); return 0;
}

运行截图:

这里我们注意我们是通过传值的方式传递参数的,假如我们进行如下的修改

  • 修改1:

运行结果:

我们观察运行结果发现出现了错误,原因是这个函数的形参是对象,是通过传值的方式传递参数的,函数体内对形参的所有修改都无法传到函数体的外面。而形参是对象的引用时,是通过传地址的方式传递参数的。

c++第五次作业的更多相关文章

  1. 耿丹CS16-2班第五次作业汇总

    Deadline: 2016-10-26 23:59 作业内容 实验4-1 求1到20的阶乘的和,其中求阶乘用函数完成. 实验4-2 写一个判素数的函数,在主函数输入一个整数,输出其是否是素数的信息. ...

  2. C 语言学习 第五次作业总结

    第五次作业,主要学习和复习的是几种循环结构的使用. 在前一次的课堂上,同学们已经学习了分支语句的使用.分支语句和循环语句配合使用,就可以写出更多的,逻辑功能丰富的代码了. 逻辑功能的丰富,也意味着学习 ...

  3. C语言第五次作业——循环结构

    C语言程序设计第五次作业--循环结构(1) (一)改错题 输出华氏摄氏温度转换表:输入两个整数lower和upper,输出一张华氏摄氏温度转换表,华氏温度的取值范围是{lower,upper},每次增 ...

  4. 17秋 软件工程 团队第五次作业 Alpha

    题目:团队作业--Alpha冲刺 17秋 软件工程 团队第五次作业 Alpha 12次Scrum 第一次Scrum 第二次Scrum 第三次Scrum 第四次Scrum 第五次Scrum 第六次Scr ...

  5. C语言基础课第五次作业

    PTA第五次作业 7-2 统计一行文本中的单词个数 一.程序代码 #include<stdio.h> int main(void) { ]; ,word=; char c; gets(st ...

  6. 17秋 软件工程 团队第五次作业 Alpha Scrum1

    题目:团队作业--Alpha冲刺 17秋 软件工程 团队第五次作业 Alpha Scrum1 各个成员在 Alpha 阶段认领的任务 伟航:督促和监督团队进度,协调组内合作 港晨:APP前端页面编写: ...

  7. 17秋 软件工程 团队第五次作业 Alpha Scrum2

    17秋 软件工程 团队第五次作业 Alpha Scrum2 今日完成的任务 杰麟:Java后端的学习: 世强:登录和注册接口编写: 港晨:完成数据库表的设计: 树民.陈翔:完成超级管理员后端框架. 其 ...

  8. 17秋 软件工程 团队第五次作业 Alpha Scrum3

    17秋 软件工程 团队第五次作业 Alpha Scrum3 今日完成的任务 杰麟:java后端学习: 世强:Android的部门基础信息模块的信息显示和对接后台: 港晨:后台管理登陆界面ui设计: 树 ...

  9. 17秋 软件工程 团队第五次作业 Alpha Scrum4

    17秋 软件工程 团队第五次作业 Alpha Scrum4 今日完成的任务 世强:部门基础信息模块数据更新.部门审核提交: 港晨:设计编写登录界面的一部分: 树民:学习python基本语法.flask ...

  10. 17秋 软件工程 团队第五次作业 Alpha Scrum5

    17秋 软件工程 团队第五次作业 Alpha Scrum5 今日完成的任务 世强:消息通知管理列表页界面编写,下拉加载效果: 港晨:编写登录界面: 树民: 伟航:学习了flask_restful框架的 ...

随机推荐

  1. iOS - 点击按钮实现简单的复制功能

    UIPasteboard使用 基本使用: - (void)copyClick { UIPasteboard *pab = [UIPasteboard generalPasteboard]; pab.s ...

  2. orcad 删除不连接符号

    1. 双击不连接符号的引脚,如下面的1脚NC 2. 进入引脚的属性界面,取消Is No Connect

  3. 算法练习之杨辉三角,杨辉三角的第 k 行,买卖股票的最佳时机

    1. 杨辉三角 给定一个非负整数 numRows,生成杨辉三角的前 numRows 行. 在杨辉三角中,每个数是它左上方和右上方的数的和. 示例: 输入: 输出: [ [], [,], [,,], [ ...

  4. (生鲜项目)03. xadmin的配置

    步骤1. 下载xadmin源码(git_hub上的源码已经不支持py3了,需要从其它老手那里获取),将本文件夹全部放置于合适的目录下(这里放到extra_apps内)2. 在settings的INST ...

  5. ABP vNext

    一.简要介绍# ABP vNext 是 ABP 框架作者所发起的新项目,截止目前 (2019 年 8 月 20 日) 已经拥有 1400 多个 Star,最新版本号为 v 0.19.0,可以尝试用于生 ...

  6. [04]Go设计模式:抽象工厂模式(Abstract Factory Pattern)

    目录 抽象工厂模式 一.简介 二.代码 三. 参考资料 抽象工厂模式 一.简介 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂 ...

  7. TestNG执行顺序控制

    1.class执行顺序控制---testng.xml之preserve-order preserve-order:用来控制<test>里面所有<classes>的执行顺序.&l ...

  8. 移动测(APP)试与web端测试的区别

    1.操作环境不同 移动端的测试环境是安卓操作环境或者iOS操作系统: web端操作环境一般是windows(如果你用的是MC电脑,那就是iOS操作系统). 2.页面的显示尺寸不同 移动端的尺寸比较多, ...

  9. Mac打开原生NTFS功能

    一.在 terminal 里输入 diskutil list 查看 U 盘的 NAME diskutil list 二.执行以下命令,输入密码 sudo nano /etc/fstab 三.把U盘信息 ...

  10. JZOJ

    题目: 三类动物A.B.C,A吃B,B吃C,C吃A.给出K句话来描述N个动物(各属于A.B.C三类之一)之间的关系,格式及意义如下:1 X Y:表示X与Y是同类: 2 X Y:表示X吃Y.K句话中有真 ...