运算符重载

一.运算符重载基本规则

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. EasyNVR摄像机网页直播中,推流组件EasyRTMP推送RTMP扩展支持HEVC(H.265)的方案

    众所周知,RTMP标准协议实际是不支持HEVC(H.265)编码格式的,同样,现行的H5标准里面,也没有对H.265的描述,所以,在很大程度上,H5网页浏览器是无法接入HEVC(H.265)的,但是, ...

  2. node端代理浏览器路由 解决浏览器跨域问题

    var _ = require('lodash'); var request = require("request"); /* @LM 2017-02-16 node端代理浏览器路 ...

  3. python:使用Djangorestframework编写post和get接口

    1.安装django pip install django 2.新建一个django工程 python manage.py startproject cainiao_monitor_api 3.新建一 ...

  4. ou can mix require and export. You can't mix import and module.exports.

    ou can mix require and export. You can't mix import and module.exports.

  5. AutoResetEvent 学生考试,老师阅卷,学生等待考试结果

    class Program { static void Main(string[] args) { )); t.Start(); Console.WriteLine("老师等待提交试卷&qu ...

  6. docker+k8s基础篇四

    Docker+K8s基础篇(四) pod控制器 A:pod控制器类型 ReplicaSet控制器 A:ReplicaSet控制器介绍 B:ReplicaSet控制器的使用 Deployment控制器 ...

  7. [转载]机器学习&深度学习经典资料汇总,全到让人震惊

    自学成才秘籍!机器学习&深度学习经典资料汇总 转自:中国大数据: http://www.thebigdata.cn/JiShuBoKe/13299.html [日期:2015-01-27] 来 ...

  8. 通过names.index()方法找到第2个eva值 ,并将其改成EVA

    names= ['alex','rain','peiqi','eva','mac','jack','eva','kangkang','jain']first_index=names.index('ev ...

  9. Navicat12下载、激活工具、激活教程

    Navicat12的下载地址如下:链接: https://pan.baidu.com/s/11CHIWO74M4-P6UG0aWsF7Q 提取码: bayk 打开激活工具Navicat_Keygen_ ...

  10. flink ETL数据处理

    Flink ETL 实现数据清洗   一:需求(针对算法产生的日志数据进行清洗拆分) 1. 算法产生的日志数据是嵌套json格式,需要拆分 2.针对算法中的国家字段进行大区转换 3.最后把不同类型的日 ...