当前课程知识点:基于Linux的C++ >  第十讲 操作符重载 >  10.3 四则运算符重载(二) >  LinuxCPP1003

返回《基于Linux的C++》慕课在线视频课程列表

LinuxCPP1003在线视频

LinuxCPP1003

下一节:LinuxCPP1004

返回《基于Linux的C++》慕课在线视频列表

LinuxCPP1003课程教案、知识点、字幕

问题四 这个四则运算符

必须重载为类的成员函数吗

不 重载为类的成员函数是可以的

但实际上

你还可以把它重载为类的友元函数

甚至就是一个普通的函数 没问题

它跟类没关系的一个普通函数也没问题

可以重载为类的友元函数

也可以重载为一个普通的函数

但是你要注意

如果你把它重载为一个普通的函数

那么这个普通函数

它没有权利访问类的私有成员

所以我们建议

将这些四则运算符重载为类的友元函数

实际上你把它重载为类的友元函数

要好过把它重载为类的成员函数

有什么优势呢 重载为类的友元函数的话

它的优势在于:

第一 友元函数中将具有显式的双操作数

因为没有this指针

所以两个操作数(左操作数和右操作数)

你都要作为函数参数传进去

它有显式的双操作数

格式是一致的

重载为类的成员函数的时候

一个左操作数是通过this指针传进去的

右操作数是通过对一个constCouple类的

一个引用传进去的

所以一个是指针 一个是引用

两个操作数的访问格式

实际上是不一样的

它不一致 有点不太美观

写的时候也要注意

所以真编程的时候

实际上有一点点别扭

那么重载为类的友元函数

又不存在这个问题

因为没有this指针了嘛

所以双操作数都是以引用的形式传进去

那么在这种情况下

双操作数的使用格式其实是一致的

还有一个地方

最重要的它不要求我们的左操作数

必须是本类的一个对象

如果你重载为一个类的成员函数 左操作数

它就固定为this所指向的这个本类对象

那如果你重载为类的友元

它不要求这一点

当然 重载为类的友元函数

它也有自己的缺点

缺点就是什么呢

还是一样 显式具有双操作数

你编程的时候就要传双参数

它比单参数传递 接口是麻烦的

所以这个左操作数你是不能够省略的

除了这一点

友元函数其实好过我们的成员函数

我们来看重载之后的这个Couple类的定义

重载的这4个操作符:

operator+、operator*、operator*、operator* 4个

都是重载为类的友元friend

重载为类的友元函数

然后传的都是双参数

你注意我们的标量乘法

我们标量乘法operator*重载了两个版本

一个左操作数是constCouple类的一个引用

一个左操作数是constint的一个引用

为什么要重载两个版本呢

因为重载的这个操作符

它并不天然地支持我们的乘法交换律

所以你必须针对于左操作数

不同的类型重载不同的版本

这是要特别注意的一个地方

关于这个数偶倍乘的运算

有一点需要说明的地方就是 第一

你最好把它重载为类的友元函数

如果不重载为类的友元函数

那左操作数是那个整数的时候

它就没有办法去计算

重载为类的成员函数

左操作数必须个Couple类的一个对象

this指针所指向的那个对象

那么如果它是k乘上Couple类的一个对象

那你怎么去处理 k是一个整数

在k上面调用operator*吗

没有啊 我们没实现呢 这是不能做的

如果非友元函数 当倍数为左操作数时

无法解析我们的乘法运算

第二 左右操作数本身

实际上是不可互换的

重载这个函数你就必须提供两个版本

两个你都得要写

它们的函数签名本身是不一致的

所以不是天然地满足我们的交换律

特别注意这一条

那我们看看 重载为类友元函数以后

内部的实现和前面那个实现

版本其实差不多 本质上是一样的

只是书写的格式有点差异

看看我们的使用

现在有了重载为友元函数的标量的乘法

我们就可以写c= k*c

k是一个整数对象

c是我们Couple类的一个对象

两者相乘 它就会调用我们的友元函数

传第一个参数k 传第二个参数c=

而不是调用我们的成员函数

如果不是重载为友元

那么她试图调用k.operator*(c)

那能调用到吗 调用不到的

如果编译器想调用成功

它就必须把k转型成我们的Couple

这个转型因为我们没有在前面写

它的转型操作 所以它是隐式的

由编译器给我们自动进行

但是这个自动进行

当你把那个单参数构造函数

写成一个explicit的时候

这个自动进行就不允许了

就禁止它这么做了

如果你禁止 它就转型不成功了嘛

如果你没禁止

但它有时候也不一定就能成功

你比如没这个构造函数

它也不成功 对吧

碰到这个情况 那这个编译器就会报错

所以你重载为友元

这个函数只要提供了 其实就没问题了

2*d其实也一样

基于Linux的C++课程列表:

第一讲 C/C++基本语法元素

-1.1 提纲

--LinuxCPP0101

-1.2 程序设计的基本概念

--LinuxCPP0102

-1.3 简单C/C++程序介绍

--LinuxCPP0103

-1.4 程序设计的基本流程

--LinuxCPP0104

-1.5 基本语法元素

--LinuxCPP0105

-1.6 程序设计风格

--LinuxCPP0106

-1.7 编程实践

--LinuxCPP0107

-第一讲 C/C++基本语法元素--编程实践提交入口

第二讲 程序控制结构

-2.1 提纲

--LinuxCPP0201

-2.2 结构化程序设计基础

--LinuxCPP0202

-2.3 布尔数据

--LinuxCPP0203

-2.4 分支结构

--LinuxCPP0204

-2.5 break语句

--LinuxCPP0205

-2.6 循环结构

--LinuxCPP0206

-2.7 编程实践

--LinuxCPP0207

-第二讲 程序控制结构--编程实践提交入口

第三讲 函数

-3.1 提纲

--LinuxCPP0301

-3.2 函数声明、调用与定义

--LinuxCPP0302

-3.3 函数调用栈框架

--LinuxCPP0303

-3.4 编程实践

--LinuxCPP0304

-第三讲 函数--编程实践提交入口

第四讲 算法

-4.1 提纲

--LinuxCPP0401

-4.2 算法概念与特征

--LinuxCPP0402

-4.3 算法描述

--LinuxCPP0403

-4.4 算法设计与实现

--LinuxCPP0404

-4.5 递归算法(一)

--LinuxCPP0405

-4.6 递归算法(二)

--LinuxCPP0406

-4.7 容错与计算复杂度

--LinuxCPP0407

-4.8 编程实践

--LinuxCPP0408

-第四讲 算法--编程实践提交入口

第五讲 程序组织与开发方法

-5.1 提纲

--LinuxCPP0501

-5.2 库与接口

--LinuxCPP0502

-5.3 随机数库(一)

--LinuxCPP0503

-5.4 随机数库(二)

--LinuxCPP0504

-5.5 作用域与生存期

--LinuxCPP0505

-5.6 典型软件开发流程(一)

--LinuxCPP0506

-5.7 典型软件开发流程(二)

--LinuxCPP0507

-5.8 编程实践

--LinuxCPP0508

-第五讲 程序组织与开发方法--编程实践提交入口

第六讲 复合数据类型

-6.1 提纲

--LinuxCPP0601

-6.2 字符

--LinuxCPP0602

-6.3 数组(一)

--LinuxCPP0603

-6.4 数组(二)

--LinuxCPP0604

-6.5 结构体

--LinuxCPP0605

-6.6 编程实践

--LinuxCPP0606

-第六讲 复合数据类型--编程实践提交入口

第七讲 指针与引用

-7.1 提纲

--LinuxCPP0701

-7.2 指针基本概念

--LinuxCPP0702

-7.3 指针与函数

--LinuxCPP0703

-7.4 指针与复合数据类型(一)

--LinuxCPP0704

-7.5 指针与复合数据类型(二)

--LinuxCPP0705

-7.6 字符串

--LinuxCPP0706

-7.7 动态存储管理(一)

--LinuxCPP0707

-7.8 动态存储管理(二)

--LinuxCPP0708

-7.9 引用

--LinuxCPP0709

-7.10 编程实践

--LinuxCPP0710

-第七讲 指针与引用--编程实践提交入口

第八讲 链表与程序抽象

-8.1 提纲

--LinuxCPP0801

-8.2 数据抽象(一)

--LinuxCPP0802

-8.3 数据抽象(二)

--LinuxCPP0803

-8.4 链表(一)

--LinuxCPP0804

-8.5 链表(二)

--LinuxCPP0805

-8.6 链表(三)

--LinuxCPP0806

-8.7 链表(四)

--LinuxCPP0807

-8.8 函数指针(一)

--LinuxCPP0808

-8.9 函数指针(二)

--LinuxCPP0809

-8.10 抽象链表(一)

--LinuxCPP0810

-8.11 抽象链表(二)

--LinuxCPP0811

-8.12 编程实践

--LinuxCPP0812

-第八讲 链表与程序抽象--编程实践提交入口

第九讲 类与对象

-9.1 提纲

--LinuxCPP0901

-9.2 程序抽象与面向对象

--LinuxCPP0902

-9.3 类类型

--LinuxCPP0903

-9.4 对象(一)

--LinuxCPP0904

-9.5 对象(二)

--LinuxCPP0905

-9.6 类与对象的成员(一)

--LinuxCPP0906

-9.7 类与对象的成员(二)

--LinuxCPP0907

-9.8 类与对象的成员(三)

--LinuxCPP0908

-9.9 继承(一)

--LinuxCPP0909

-9.10 继承(二)

--LinuxCPP0910

-9.11 继承(三)

--LinuxCPP0911

-9.12 多态(一)

--LinuxCPP0912

-9.13 多态(二)

--LinuxCPP0913

-9.14 编程实践

--LinuxCPP0914

-第九讲 类与对象--编程实践提交入口

第十讲 操作符重载

-10.1 提纲

--LinuxCPP1001

-10.2 四则运算符重载(一)

--LinuxCPP1002

-10.3 四则运算符重载(二)

--LinuxCPP1003

-10.4 关系与下标操作符重载

--LinuxCPP1004

-10.5 赋值操作符重载(一)

--LinuxCPP1005

-10.6 赋值操作符重载(二)

--LinuxCPP1006

-10.7 赋值操作符重载(三)

--LinuxCPP1007

-10.8 赋值操作符重载(四)

--LinuxCPP1008

-10.9 赋值操作符重载(五)

--LinuxCPP1009

-10.10 流操作符重载(一)

--LinuxCPP1010

-10.11 流操作符重载(二)

--LinuxCPP1011

-10.12 流操作符重载(三)

--LinuxCPP1012

-10.13 操作符重载总结

--LinuxCPP1013

-10.14 编程实践

--LinuxCPP1014

-第十讲 操作符重载--编程实践提交入口

第十一讲 泛型编程

-11.1 提纲

--LinuxCPP1101

-11.2 泛型编程概览

--LinuxCPP1102

-11.3 异常处理机制(一)

--LinuxCPP1103

-11.4 异常处理机制(二)

--LinuxCPP1104

-11.5 运行期型式信息(一)

--LinuxCPP1105

-11.6 运行期型式信息(二)

--LinuxCPP1106

-11.7 模板与型式参数化

--LinuxCPP1107

-11.8 题外话:术语翻译

--LinuxCPP1108

-11.9 泛型编程实践(一)

--LinuxCPP1109

-11.10 泛型编程实践(二)

--LinuxCPP1110

-11.11 泛型编程实践(三)

--LinuxCPP1111

-11.12 泛型编程实践(四)

--LinuxCPP1112

-11.13 泛型编程实践(五)

--LinuxCPP1113

-11.14 泛型编程实践(六)

--LinuxCPP1114

-11.15 泛型编程实践(七)

--LinuxCPP1115

-11.16 泛型编程实践(八)

--LinuxCPP1116

-11.17 泛型编程实践(九)

--LinuxCPP1117

-11.18 泛型编程实践(十)

--LinuxCPP1118

-11.19 编程实践

--LinuxCPP1119

-第十一讲 泛型编程--编程实践提交入口

第十二讲 Linux系统编程基础

-12.1 提纲

--LinuxCPP1201

-12.2 程序执行环境(一)

--LinuxCPP1202

-12.3 程序执行环境(二)

--LinuxCPP1203

-12.4 程序执行环境(三)

--LinuxCPP1204

-12.5 程序执行环境(四)

--LinuxCPP1205

-12.6 输入输出(一)

--LinuxCPP1206

-12.7 输入输出(二)

--LinuxCPP1207

-12.8 文件系统

--LinuxCPP1208

-12.9 设备

--LinuxCPP1209

-12.10 库(一)

--LinuxCPP1210

-12.11 库(二)

--LinuxCPP1211

-12.12 makefile文件(一)

--LinuxCPP1212

-12.13 makefile文件(二)

--LinuxCPP1213

-12.14 makefile文件(三)

--LinuxCPP1214

-12.15 编程实践

--LinuxCPP1215

-第十二讲 Linux系统编程基础--编程实践提交入口

第十三讲 进程编程

-13.01 提纲

--LinuxCPP1301

-13.02 进程基本概念

--LinuxCPP1302

-13.03 信号

--LinuxCPP1303

-13.04 进程管理(一)

--LinuxCPP1304

-13.05 进程管理(二)

--LinuxCPP1305

-13.06 进程管理(三)

--LinuxCPP1306

-13.07 进程间通信(一)

--LinuxCPP1307

-13.08 进程间通信(二)

--LinuxCPP1308

-13.09 进程间通信(三)

--LinuxCPP1309

-13.10 进程间通信(四)

--LinuxCPP1310

-13.11 进程池

--LinuxCPP1311

-13.12 编程实践

--LinuxCPP1312

-第十三讲 进程编程--编程实践提交入口

第十四讲 线程编程

-14.1 提纲

--LinuxCPP1401

-14.2 线程基本概念

--LinuxCPP1402

-14.3 线程管理(一)

--LinuxCPP1403

-14.4 线程管理(二)

--LinuxCPP1404

-14.5 线程管理(三)

--LinuxCPP1405

-14.6 线程管理(四)

--LinuxCPP1406

-14.7 线程同步机制(一)

--LinuxCPP1407

-14.8 线程同步机制(二)

--LinuxCPP1408

-14.9 C++11线程库(一)

--LinuxCPP1409

-14.10 C++11线程库(二)

--LinuxCPP1410

-14.11 C++11线程库(三)

--LinuxCPP1411

-14.12 C++11线程库(四)

--LinuxCPP1412

-14.13 C++11线程库(五)

--LinuxCPP1413

-14.14 编程实践

--LinuxCPP1414

-第十四讲 线程编程--编程实践提交入口

第十五讲 网络编程

-15.1 提纲

--LinuxCPP1501

-15.2 Internet网络协议

--LinuxCPP1502

-15.3 套接字(一)

--LinuxCPP1503

-15.4 套接字(二)

--LinuxCPP1504

-15.5 编程实践

--LinuxCPP1505

-第十五讲 网络编程--编程实践提交入口

课程文档

-课程PDF文件

LinuxCPP1003笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。