活动介绍

C++运算符重载与类型转换全解析

立即解锁
发布时间: 2025-08-19 01:36:31 阅读量: 2 订阅数: 6
PDF

C++面向对象编程入门与实践

# C++ 运算符重载与类型转换全解析 ## 1. 转换时机与方式 在进行类型转换时,我们常常会面临选择:是使用目标类的单参数构造函数,还是源类的转换运算符呢?通常情况下,这两种方式都可行,但有时情况会限制我们的选择。 ### 1.1 选择原则 - **使用单参数构造函数的情况**:当你使用一个购买的类库,且无法访问其源代码时,如果将该类库中的对象作为转换的源对象,你只能访问目标类,此时就需要使用目标类的单参数构造函数。 - **使用转换运算符的情况**:若类库对象是转换的目标对象,那么你必须使用源类的转换运算符。 ## 2. UML 类图 UML(统一建模语言)类图为我们提供了一种全新的视角来审视面向对象程序,它能帮助我们更好地理解程序中类与类之间的关系。 ### 2.1 类的表示 在 UML 类图中,类用矩形表示。例如,在 TIMES1 程序中有两个类:time12 和 time24,它们在 UML 类图中就是两个矩形,如下所示: ```mermaid classDiagram class time12 class time24 ``` 每个类矩形被水平线分割成多个部分,类名位于顶部部分。此外,还可以包含成员数据(在 UML 中称为属性)和成员函数(称为操作)的部分。 ### 2.2 类之间的关联 类与类之间可能存在各种关系,在 TIMES1 程序中,类之间的关系是关联。关联用连接两个类矩形的线表示。 关联的概念源于现实世界中实体之间的明显关系,例如司机与汽车、书籍与图书馆、赛马与赛马场。如果这些实体在程序中被表示为类,那么它们之间就存在关联。 在 TIMES2.CPP 程序中,time12 类与 time24 类相关联,因为我们可以将一个类的对象转换为另一个类的对象。 类关联实际上意味着类的对象之间存在某种关系。通常,如果一个类的对象调用另一个类对象的成员函数(操作),或者一个类的属性是另一个类的对象,那么这两个类就存在关联。 在 TIMES1 程序中,time12 类的对象 t12 调用了 time24 类对象 t24 中的转换例程 operator time12(),这一调用在 main() 函数中的语句如下: ```cpp time12 t12 = t24; // convert time24 to time12 ``` 这种调用在 UML 类图中用两个类之间的关联线表示。 ### 2.3 导航性 我们可以在关联线上添加开放箭头来表示关联的方向或导航性。由于 time12 调用 time24,箭头从 time12 指向 time24,这被称为单向关联。如果两个类相互调用对方的操作,那么关联线的两端都会有箭头,这被称为双向关联。导航性箭头在 UML 中是可选的。 ## 3. 运算符重载与转换的陷阱 运算符重载和类型转换为我们提供了创建一种全新语言的机会,但同时也可能带来一些问题。当 a、b 和 c 是用户定义类的对象,并且 + 运算符被重载时,语句 `a = b + c;` 的含义可能与 a、b 和 c 是基本数据类型变量时完全不同。 ### 3.1 使用相似的含义 使用重载运算符执行的操作应尽可能与对基本数据类型执行的操作相似。例如,虽然可以将 + 符号重载为执行减法操作,但这显然会使代码更难理解。 重载运算符时,需要确保对某个类的对象执行特定操作是有意义的。例如,在本章中,我们展示了如何为 English Distance 类重载 + 运算符,两个距离相加显然是有意义的;我们也为 String 类重载了 + 运算符,将两个字符串相加表示将一个字符串放在另一个字符串后面形成第三个字符串,这也有直观的解释。但对于许多类来说,谈论“添加”它们的对象可能并不合理,例如,你可能不想将包含个人数据的 employee 类的两个对象相加。 ### 3.2 使用相似的语法 使用重载运算符的方式应与使用基本类型的方式相同。例如,如果 alpha 和 beta 是基本类型,语句 `alpha += beta;` 会将 alpha 设置为 alpha 和 beta 的和。任何重载版本的该运算符都应执行类似的操作,可能与 `alpha = alpha + beta;`(其中 + 被重载)的操作相同。 如果重载了一个算术运算符,为了保持一致性,可能需要重载所有算术运算符,以避免混淆。同时,运算符的一些语法特性是不能改变的,例如,不能将二元运算符重载为一元运算符,反之亦然。 ### 3.3 克制使用 要记住,如果你重载了 + 运算符,不熟悉你代码的人需要进行大量研究才能理解语句 `a = b + c;` 的真正含义。如果重载运算符的数量过多,并且运算符的使用方式不直观,那么使用它们的初衷就会丧失,代码阅读会变得更加困难。因此,应谨慎使用重载运算符,仅在使用方式明显时使用。当有疑问时,使用函数而不是重载运算符,因为函数名可以明确表达其用途。例如,如果你编写一个函数来获取字符串的左侧部分,最好将其命名为 getleft(),而不是尝试重载某个运算符(如 &&)来完成相同的任务。 ### 3.4 避免歧义 避免使用单参数构造函数和转换运算符来执行相同的转换(例如,将 time24 转换为 time12)。因为编译器不知道该使用哪种转换方式,会发出错误信号。所以,应避免以多种方式进行相同的转换。 ### 3.5 并非所有运算符都能重载 以下运算符不能被重载:成员访问或点运算符 (.)、作用域解析运算符 (::)、条件运算符 (?:)。此外,尚未介绍的指向成员的运算符 (->) 也不能被重载。同时,不能创建新的运算符(如 *&)并尝试重载它们,只能重载现有的运算符。 ## 4. 关键字 explicit 和 mutable ### 4.1 explicit 关键字:防止隐式转换 在某些情况下,你可能希望允许特定的转换,但不希望发生其他不必要的转换。对于转换运算符,防止转换很简单,只需不定义该运算符即可。但对于构造函数,情况就不同了。 标准 C++ 引入了 explicit 关键字来解决这个问题。该关键字放在单参数构造函数的声明之前。以下是一个示例程序: ```cpp // explicit.cpp #include <iostream> using namespace std; class Distance { private: const float MTF; // meters to feet int feet; float inches; public: // no-args constructor Distance() : feet(0), inches(0.0), MTF(3.280833F) {} // EXPLICIT one-arg constructor explicit Distance(float meters) : MTF(3.280833F) { float fltfeet = MTF * meters; feet = int(fltfeet); inches = 12 * (fltfeet - feet); } void showdist() { cout << feet << "\'-" << inches << '\"'; } }; int main() { void fancyDist(Distance); // declaration Distance dist1(2.35F); // uses 1-arg constructor to convert meters to Distance // Distance dist1 = 2.35F; // ERROR if ctor is explicit cout << "\ndist1 = "; dist1.showdist(); float mtrs = 3.0F; cout << "\ndist1 "; // fancyDist(mtrs); // ERROR if ctor is explicit return 0; } void fancyDist(Distance d) { cout << "(in ```
corwn 最低0.47元/天 解锁专栏
赠100次下载
继续阅读 点击查看下一篇
profit 400次 会员资源下载次数
profit 300万+ 优质博客文章
profit 1000万+ 优质下载资源
profit 1000万+ 优质文库回答
复制全文

相关推荐

SW_孙维

开发技术专家
知名科技公司工程师,开发技术领域拥有丰富的工作经验和专业知识。曾负责设计和开发多个复杂的软件系统,涉及到大规模数据处理、分布式系统和高性能计算等方面。
最低0.47元/天 解锁专栏
赠100次下载
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
千万级 优质文库回答免费看
立即解锁

专栏目录

最新推荐

零信任架构的IoT应用:端到端安全认证技术详解

![零信任架构的IoT应用:端到端安全认证技术详解](https://img-blog.csdnimg.cn/20210321210025683.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMzI4MjI4,size_16,color_FFFFFF,t_70) # 摘要 随着物联网(IoT)设备的广泛应用,其安全问题逐渐成为研究的焦点。本文旨在探讨零信任架构下的IoT安全认证问题,首先概述零信任架构的基本概念及其对Io

虚拟助理引领智能服务:酒店行业的未来篇章

![虚拟助理引领智能服务:酒店行业的未来篇章](https://images.squarespace-cdn.com/content/v1/5936700d59cc68f898564990/1497444125228-M6OT9CELKKA9TKV7SU1H/image-asset.png) # 摘要 随着人工智能技术的发展,智能服务在酒店行业迅速崛起,其中虚拟助理技术在改善客户体验、优化运营效率等方面起到了关键作用。本文系统地阐述了虚拟助理的定义、功能、工作原理及其对酒店行业的影响。通过分析实践案例,探讨了虚拟助理在酒店行业的应用,包括智能客服、客房服务智能化和后勤管理自动化等方面。同时,

【仿真模型数字化转换】:从模拟到数字的精准与效率提升

![【仿真模型数字化转换】:从模拟到数字的精准与效率提升](https://img-blog.csdnimg.cn/42826d38e43b44bc906b69e92fa19d1b.png) # 摘要 本文全面介绍了仿真模型数字化转换的关键概念、理论基础、技术框架及其在实践中的应用流程。通过对数字化转换过程中的基本理论、关键技术、工具和平台的深入探讨,文章进一步阐述了在工程和科学研究领域中仿真模型的应用案例。此外,文中还提出了数字化转换过程中的性能优化策略,包括性能评估方法和优化策略与方法,并讨论了数字化转换面临的挑战、未来发展趋势和对行业的长远意义。本文旨在为专业人士提供一份关于仿真模型数

地震波正演的逆问题:从正演到反演的深入研究与应用

![地震波正演的逆问题:从正演到反演的深入研究与应用](https://img-blog.csdnimg.cn/baf501c9d2d14136a29534d2648d6553.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Zyo6Lev5LiK77yM5q2j5Ye65Y-R,size_20,color_FFFFFF,t_70,g_se,x_16) # 摘要 本文系统地论述了地震波正演与反演技术的理论基础、实现方法以及实际应用。首先概述了地震波正演的逆问题,然后详细介绍了地震波传播

【心电信号情绪识别在虚拟现实中的应用研究】:探索虚拟世界中的情绪分析

![【心电信号情绪识别在虚拟现实中的应用研究】:探索虚拟世界中的情绪分析](https://www.radsport-rennrad.de/wp-content/uploads/2018/10/leistungstest-radsport.jpg) # 摘要 情绪识别技术与虚拟现实的结合为沉浸式体验带来了新的可能性。本文首先概述了情绪识别与虚拟现实的基本概念,接着深入探讨了心电信号(ECG)的理论基础,包括其产生原理、采集方法和数据处理技术。文中详细分析了心电信号情绪识别算法,并研究了机器学习和深度学习在情绪识别中的应用。此外,本文还探讨了心电信号情绪识别技术在虚拟现实中的实际应用,并通过具

手机Modem协议在网络环境下的表现:分析与优化之道

![手机Modem协议开发快速上手.docx](https://img-blog.csdnimg.cn/0b64ecd8ef6b4f50a190aadb6e17f838.JPG?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBATlVBQeiInOWTpQ==,size_20,color_FFFFFF,t_70,g_se,x_16) # 摘要 Modem协议在网络通信中扮演着至关重要的角色,它不仅定义了数据传输的基础结构,还涉及到信号调制、通信流程及错误检测与纠正机制。本文首先介

【飞机缺陷检测模型压缩加速】:减小模型尺寸,加速推理过程

![【飞机缺陷检测模型压缩加速】:减小模型尺寸,加速推理过程](https://static.mianbaoban-assets.eet-china.com/xinyu-images/MBXY-CR-c3b4ad4ba4139993bf9baedd09c1c762.png) # 摘要 随着深度学习在飞机缺陷检测领域应用的增多,模型压缩和加速技术成为提升检测效率的关键。本文首先介绍了深度学习模型压缩的理论基础,包括其重要性和技术分类,随后探讨了模型加速技术实践,如深度学习框架的选择和模型剪枝、量化实践。通过应用案例分析,展示了模型压缩加速技术在实际飞机缺陷检测中的应用及其带来的性能改善。最后,

【多源数据整合王】:DayDreamInGIS_Geometry在不同GIS格式中的转换技巧,轻松转换

![【多源数据整合王】:DayDreamInGIS_Geometry在不同GIS格式中的转换技巧,轻松转换](https://community.esri.com/t5/image/serverpage/image-id/26124i748BE03C6A81111E?v=v2) # 摘要 本论文详细介绍了DayDreamInGIS_Geometry这一GIS数据处理工具,阐述了其核心功能以及与GIS数据格式转换相关的理论基础。通过分析不同的GIS数据格式,并提供详尽的转换技巧和实践应用案例,本文旨在指导用户高效地进行数据格式转换,并解决转换过程中遇到的问题。文中还探讨了转换过程中的高级技巧、

物联网技术:共享电动车连接与控制的未来趋势

![物联网技术:共享电动车连接与控制的未来趋势](https://read.nxtbook.com/ieee/potentials/january_february_2020/assets/4cf66356268e356a72e7e1d0d1ae0d88.jpg) # 摘要 本文综述了物联网技术在共享电动车领域的应用,探讨了核心的物联网连接技术、控制技术、安全机制、网络架构设计以及实践案例。文章首先介绍了物联网技术及其在共享电动车中的应用概况,接着深入分析了物联网通信协议的选择、安全机制、网络架构设计。第三章围绕共享电动车的控制技术,讨论了智能控制系统原理、远程控制技术以及自动调度与充电管理

【C#数据绑定高级教程】:深入ListView数据源绑定,解锁数据处理新技能

![技术专有名词:ListView](https://androidknowledge.com/wp-content/uploads/2023/01/customlistthumb-1024x576.png) # 摘要 随着应用程序开发的复杂性增加,数据绑定技术在C#开发中扮演了关键角色,尤其在UI组件如ListView控件中。本文从基础到高级技巧,全面介绍了C#数据绑定的概念、原理及应用。首先概述了C#中数据绑定的基本概念和ListView控件的基础结构,然后深入探讨了数据源绑定的实战技巧,包括绑定简单和复杂数据源、数据源更新同步等。此外,文章还涉及了高级技巧,如数据模板自定义渲染、选中项