C++ Primer Plus第十一章笔记

目录

运算符重载

概述

1.2 重载限制

友元简介

创建友元

常用的友元:重载 << 运算符

重载运算符:作为成员函数还是非成员函数

类的自动转换和强制类型转换

两种类型转换

转换函数

运算符重载

操作符重载(Operator Overloading)是一种形式的C++多态。

概述

函数重载(函数多态):定义多个名称相同但特征标(参数列表)不同的函数。

函数重载(function overloading)、函数多态(function polymorphism)。

C++允许将运算符重载扩展到用户定义的类型。要重载运算符,需使用被称为运算符函数的特殊函数形式。运算符函数的格式如下:

// op表示要重载的操作符符号,如 operator +()
operator op(argument-list)// 如:operator []() 数组索引运算符

op必须是有效的C++运算符,不能虚构一个新的操作符号。

⚠️警告:不要返回指向局部变量或临时对象的引用。函数执行完毕之后,局部变量和临时对象将消失,引用将指向不存在的数据。

1.2 重载限制

  • 重载后的运算符必须至少有一个是用户定义的类型。目的:防止用户对标准类型重载运算符。

  • 使用运算符时,不能违反运算符原来的句法规则。不能改变优先级。

  • 不能创建新运算符。如: operator **() 函数表示求幂(❌不允许)

  • **不能重载**下面的运算符

    • sizeof运算符
    • 成员运算符(.
    • 成员指针运算符(.*
    • 作用域解析运算符(::
    • 条件运算符(:?
    • 一个RTTI运算符(typeid
    • 强制类型转换运算符(const_cast、dynamic_cast、reinterpret_cast、static_cast)。
  • 只能通过成员函数重载的操作符

    • 赋值运算符(=
    • 函数调用运算符(()
    • 下标运算符([]
    • 通过指针访问类成员的运算符(->

友元简介

C++提供另外一种形式的访问权限:友元。友元有3种:

  • 友元函数
  • 友元类
  • 友元成员函数

通过让函数成为类的友元,可以赋予该函数与类的成员函数系统的访问权限。

在为类重载二元运算符时(带两个参数的运算符)常常需要友元。

对于非成员重载运算符函数来说,运算符表达式左边的操作数对应于运算符函数的的第一个参数,运算符表达式右边的操作数对应于运算符函数的第二个参数,而原来的成员函数则按相反的顺序处理操作数。

通过友元函数,可以让非成员函数也可与类成员函数相同的访问权限。

创建友元

  • 创建原型

    创建友元函数,将其原型放在类声明中,并在原型声明前加上关键字 friend

    friend Time operator * (double m,const Time & t)
    /** operator*() 函数是在类声明中声明的,但不是成员函数,因此不能使用成员运算符来调用* operator*() 函数不是成员函数,但它与成员函数的访问权限相同*/
  • 编写函数定义 因不是成员函数,所以不需要使用 Time:: 限定符。不要在定义中使用关键字 friend

    Time operator*(double m, const Time & t) // 友元不用在函数定义中使用
    {Time result;long totalminutes = t.hours * mult * 60 + t.minutes * mult;result.hours = totalminutes / 60;result.minutes = totalminutes % 60;return result;
    }

常用的友元:重载 << 运算符

<<运算符是C和C++的位运算符,将值中的位左移。ostream类对该运算符进行重载,将其转换为一个输出工具。

ostream类声明中都包含相应的重载的 operator<<()定义。

ostream & operator <<(ostream & os, const c_name & obj)
{os << ...; // 显示内容return os;
}

⚠️警告:只有在类声明中的原型才能使用 friend 关键字。除非函数定义也是原型,否则不能在函数定义中使用该关键字。

重载运算符:作为成员函数还是非成员函数

对于很多运算符来说,可选择使用成员函数或非成员函数来实现运算符重载。而非成员函数则必须是友元函数才能访问类的私有数据。

// ---------------- Time 类 --- 注意:加法属于二元操作符(需要两个操作数)-----
Time operator+(const Time & t) const; //成员函数版本(一个操作数通过this指针隐式磁道没,而另一个则是作为函数参数显式传递)friend Time operator+(const Time & t1,const Time & t2);// 非成员函数版本(友元函数,两个操作数都是作为参数传递)

⚠️注意:非成员版本的重载运算符函数所需的形参数目与运算符使用的操作数数目相同;而成员函数所需的参数数目少一个,因为其中的一个操作数是被隐式地传递的调用对象。

T1 = T2 + T3;T1 = T2.operator+(T3); // 成员函数格式
T1 = operator+(T2,T3); //非成员函数格式

⚠️注意:在定义运算符是,必须选择其一,而不能同时选择两种格式,否则会出现二义性,从而导致编译错误。

类的自动转换和强制类型转换

将一个标准类型变量的值赋给另一种标准类型的变量时,如果两种类型兼容,则C++自动将该值转换为接收变量的类型。但是也会伴随精度丢失的情况发生。

两种类型转换

在无法完成自动转换时,可以使用强制类型转换。

  • 隐式转换

    //使用构造函数创建一个临时对象并初始化,然后采用逐成员赋值的方式将临时对象的内容复制到myCat中,这种方式称为隐式转换。
    Stonewt(double lbs);
    Stonewt myCat;
    myCat = 19.6;
    // 只有接受一个参数的构造函数才能作为转换函数

    隐式转换是自动进行,而不需要显式强制类型转换。

  • 显式转换

    将构造函数用于自动类型转换会出现意外情况,所以C++新特性使用 关键字 explicit 来关闭自动特性。

    // 声明构造函数的格式
    explicit Stonewt(double lbs); //不隐式转换(显式转换)

只接受一个参数的构造函数定义了从参数类型类类型的转换。如果在声明中使用关键字 explicit,则只用于显式强制类型转换。否则会用于如下的隐式转换。(避免存在二义性

  • 将Stonewt对象初始化为doubel值时
  • 将double值赋给Stonewt对象时。
  • 将double值传递给接受Stonewt参数的函数时。
  • 上述任一情况下,使用可转换为double类型的内置类型时。

转换函数

C++运算符函数 ----- 转换函数:用户自定义的强制类型转换,可进行类似使用内置强制类型转换一样的方式。

operator typeName(); // typeName指要转换成的类型operator double(); //转换为double类型的函数原型

⚠️转换函数的注意点

  • 必须是类方法:需要通过类对象来调用,从而告知函数要转换的值。
  • 不能指定返回类型
  • 不能有参数

转换函数没有返回类型、没有参数、但必须返回转换后的值(虽然没有声明返回值的类型)

C++为类提供的类型转换

  • 只有一个参数的类构造函数用于将类型与该参数相同的值转换为类类型。在构造函数声明中使用 explicit可防止隐式转换,而只允许显式转换。
  • 被称为转换函数的特殊类成员运算符函数,用于将类对象转换为其他类型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/184616.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

夜莺项目发布 v6.4.0 版本,新增全局宏变量功能

大家好&#xff0c;夜莺项目发布 v6.4.0 版本&#xff0c;新增全局宏变量功能&#xff0c;本文为大家简要介绍一下相关更新内容。 全局宏变量功能 像 SMTP 的配置中密码类型的信息&#xff0c;之前都是以明文的方式在页面展示&#xff0c;夜莺支持全局宏变量之后&#xff0c;可…

android11-隐藏状态栏和导航栏

隐藏导航栏 /android11/frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml diff --git a/frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml b/frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml index ba6b6956f1..6db2348…

在Linux中如何检查网络问题

ping命令&#xff1a; ping example.com示例输出&#xff1a; PING example.com (93.184.216.34) 56(84) bytes of data. 64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq1 ttl55 time10.3 ms 64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq2 ttl55 time9.…

从 JSON 转 Java 实体的多种方法详解

将 JSON 数据转换为 Java 对象是现代应用程序开发中常见的任务。在 Java 中&#xff0c;有多种方法可以实现这一目标。本文将详细介绍几种常见的方法&#xff0c;以及它们的优缺点。 1. 手动映射&#xff08;Manual Mapping&#xff09; 手动映射是最基础的方法之一&#xff…

kibana安装

kibana安装下载注意事项 地址&#xff1a;curl -O https://artifacts.elastic.co/downloads/kibana/kibana-7.16.3-linux-x86_64.tar.gz 下载后直接解压启动即可 1. 但需要使用非root用户启动 &#xff0c;root用户启动会报错 2. kibana需要和elasticsearch版本一致 不然…

力扣labuladong一刷day21天滑动哈希算法共2题

力扣labuladong一刷day21天滑动哈希算法共2题 文章目录 力扣labuladong一刷day21天滑动哈希算法共2题一、187. 重复的DNA序列二、28. 找出字符串中第一个匹配项的下标 一、187. 重复的DNA序列 题目链接&#xff1a;https://leetcode.cn/problems/repeated-dna-sequences/descr…

管理Android12系统的WLAN热点

大家好!我是编码小哥,欢迎关注,持续分享更多实用的编程经验和开发技巧,共同进步。 要创建一个APK管理Android 12系统的WLAN热点,你需要遵循以下步骤: 1. 获取必要的权限和API访问权限。在AndroidManifest.xml文件中添加以下权限: ```xml <uses-permission android:…

vue3通过el-dropdown实现动态菜单切换页面

这是效果图 首先是主页index.vue <template><el-row><el-col :span"20"><!-- 顶部菜单 --><div v-if"showTop"><topmenu /></div><!-- 右侧下方区域动态切换的内容 --><div style"flex: 1;&quo…

oracle varchar2 和 nvarchar2的区别

oracle varchar2 和 nvarchar2的区别 VARCHAR2和NVARCHAR2在数据库中都用于存储变长字符数据&#xff0c;但两者在存储方式和字符长度上存在一些不同。以下是VARCHAR2和NVARCHAR2的区别&#xff1a; 存储方式&#xff1a;VARCHAR2是存储以字节为单位的字符串&#xff0c;而NV…

Qt Creator使用Heob检测内存泄漏

转自Qt windows MinGW编译环境下内存泄漏排查工具 heob使用教程-CSDN博客 问题描述 最近开发的一个小项目&#xff0c;正常使用时&#xff0c;占用内存随时间增加越来越大&#xff0c;直至程序崩溃。 内存泄漏排查工具heob 在Qt creator4.6以后&#xff0c;可以使用heob进行内…

css浮动属性学习

在此文&#xff0c; html菜单的基本制作-CSDN博客 已经看到css 浮动属性的效果&#xff1b;下面单独看一下浮动属性&#xff1b; 做4个div&#xff0c;设置不同的背景色&#xff0c;不为div添加float属性&#xff1b;效果如下&#xff1b; 因为div是块级元素&#xff0c;默认…

上海震坤行:水泥行业数字化采购的趋势、策略与实践

上海震坤行&#xff1a;水泥行业数字化采购的趋势、策略与实践 在中国水泥协会发布的《2023年上半年水泥行业经济运行及下半年展望》中提到了水泥行业的发展现状——2023年上半年&#xff0c;在全球经济增长放缓、国内经济延续恢复态势、但市场需求不足的宏观环境下&#xff0…

HarmonyOS开发—Arkts循环渲染(ForEach)深入运用详解【鸿蒙专栏-16】

文章目录 ArkTS ForEach接口详解与应用示例ForEach接口概述介绍接口描述参数说明键值生成规则默认规则组件创建规则首次渲染非首次渲染使用场景高级用法条件渲染逻辑LazyForEach的性能优化渲染结果预期ForEach的错误使用案例与性能降低渲染结果非预期渲染性能降低结语ArkTS For…

试用程序实现不使用缓存字节数组的方法复制C盘根目录下的a,jpg到E盘下的a.jpg

import java.io.*;public class FileCopier {public static void main(String[] args) {String sourcePath "C:\\a.jpg"; // 源文件路径String destinationPath "E:\\a.jpg"; // 目标文件路径copyFile(sourcePath, destinationPath);System.out.printl…

全新MacBook 前端装机流程

1.安装brew 啥也别说&#xff0c;直接用下面这个代码&#xff0c;别问为啥&#xff0c;没有翻墙软件千万别去官网下载&#xff0c;都是血的教训。 /usr/bin/ruby -e "$(curl -fsSL https://cdn.jsdelivr.net/gh/ineo6/homebrew-install/install)"2.安装nvm 又到了…

python使用subprocess.Popen多线程的cmd命令交互

python使用subprocess.Popen多线程的cmd命令交互 我们创建了一个CmdThread类&#xff0c;该类继承自threading.Thread&#xff0c;并重写了run()方法,我们使用subprocess.Popen()执行指定的命令&#xff0c;并通过管道获取命令的输出。然后&#xff0c;我们逐行读取输出&#…

电商API数据接口|拼多多商品订单物流接口的接入

拼多多是一家中国的电商平台&#xff0c;提供了多语言环境下的接口&#xff0c;以便开发者能够在各种语言环境中使用拼多多的功能和服务。以下是拼多多多语言环境下的接口介绍&#xff1a; 1. 用户认证接口&#xff1a;通过该接口&#xff0c;开发者可以实现用户的注册、登录和…

【Windows】解决Windows11错误0x80190001

1. 安装Fiddler网络调试工具 下载链接&#xff1a;Fiddler Classic 注&#xff1a;获取安装包的过程中可能要获取邮箱信息&#xff0c;但不用验证邮箱&#xff0c;大概是给你的邮箱发广告信息&#xff0c;问题不大。 在“开始”界面找到Fiddler Classic&#xff0c;点击运行…

攻防渗透常用命令速查

攻防渗透常用命令速查 建议配合CTRL+F进行查询 目录 攻防渗透常用命令速查 目录反弹Shell bashcurlhttpjavassh无记录shellpython交互shell图片马制作按首字母排序 AlliNArjundirsearchdirmapEHoleENScan_GOfindffuffscangrephping3hydraJNDIHackBrowerserDatakscanksubdomai…

办公用品领用管理系统能做什么?如何优化企业运营管理工作?

办公用品相对于公司其他的固定资产来说&#xff0c;大多数都属于低值易耗品&#xff0c;东西虽小但必须要有&#xff0c;且种类较多&#xff0c;因此制定适当的制度对于日常管理来说是十分必要的流程&#xff0c;行政人员也需要根据不同的需求去进一步的完善。然而&#xff0c;…