C++证道之路第十五章友元、异常和其他

ops/2024/10/23 9:32:22/

 友元

友元函数:

友元函数不是类的成员函数,但能够访问类的私有(private)成员和保护(protected)成员。友元函数定义在类的外部,但在类的定义中通过friend关键字声明。友元函数可以是普通函数,也可以是其他类的成员函数。

友元类:

如果一个类B是另一个类A的友元,那么类B的所有成员函数都可以访问类A的私有成员和保护成员。友元关系是单向的,不是传递的,也不是交换的。

友元的使用场景:

友元通常用于重载操作符,以便能够访问类的私有数据成员。然而,过度使用友元可能会破坏封装性,因此应谨慎使用。

类并非只能拥有友元函数,也可以将类作为友元。

在这种情况下,友元类的所有方法都可以访问原始类的私有成员和保护成员。

另外也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元。

哪些函数、成员函数或类为友元是由类定义的,而不能从外部强加友情。因此,尽管友元被授予从外部访问类的私有部分的权限,但它们并不与面向对象的编程思想相悖;相反,它们提高了公有接口的灵活性。

嵌套类

在C++中,可以将类声明放在另一个类中。在另一个类中声明的类被称为嵌套类,它通过提供新的类型类作用域来避免名称混乱。包含类的成员函数可以创建和使用被嵌套类的对象;而仅当声明位于公有部分,才能在包含类的外面时候用嵌套类,而且必须使用作用域解析运算符。

对类进行嵌套与包含并不同。包含意味着将类对象作为另一个类的成员,而对类进行嵌套不创建类成员,而是定义了一种类型,与该类型仅在包含嵌套类声明的类中有效。

定义与声明:

嵌套类是在另一个类的定义中声明的类。嵌套类的作用域被限制在其包含它的类的内部。嵌套类可以是公有(public)、私有(private)或保护(protected)的,这决定了它们如何被外部世界或派生类访问。

使用场景:

嵌套类常用于实现辅助类或仅与包含它的类紧密相关的类。它们有助于组织代码和隐藏实现细节,同时提供对包含类的成员的访问。

访问权限:

嵌套类的访问权限取决于其声明在包含类中的位置。公有嵌套类可以从包含类的外部访问,私有嵌套类则只能由包含类的成员函数和友元访问。

异常

下面介绍如何使用异常机制来处理错误。C++异常是对程序运行过程中发生的异常情况。异常提供了将控制权从程序的一个部分传递到另一个部分的途径。对异常的处理有3个组成部分:

引发异常;

使用处理程序捕获异常;

使用try块。

try块:

try块用于包含可能引发异常的代码。如果在try块中的代码执行过程中引发异常,程序控制将立即跳出try块,并查找匹配的catch块。

catch块:

catch块用于捕获和处理异常。每个catch块都指定它能够处理的异常类型。当异常被抛出时,控制流会跳转到第一个能够处理该异常类型的catch块。

throw语句:

throw语句用于显式地引发异常。它后面通常跟随一个值,该值描述了异常的特性。当throw语句被执行时,当前的函数执行会立即停止,异常开始传播。

异常的传播:

如果函数无法处理引发的异常,它会将该异常传播给调用它的函数。这个过程会沿着函数调用栈向上进行,直到找到能够处理该异常的catch块或程序终止。

异常的规格:

虽然C++11及之后的版本不再推荐使用异常规格来限制函数可能抛出的异常类型,但了解这一概念有助于理解C++的异常处理机制的历史演变。在旧版本的C++中,异常规格用于指定函数可能抛出的异常类型列表。

其他:

abort()函数用于立即终止程序的执行,不执行任何清理操作。它通常用于处理无法恢复的错误情况。

exit()函数也用于终止程序,但它允许程序执行清理操作(如全局对象的析构函数)。它可以接受一个整数值作为退出状态码。

总结

友元使得能够为类开发更灵活的接口。类可以将其他函数、其他类和其他类成员函数作为友元。在某些情况下,可能需要使用前向声明,需要特别注意类和方法声明的顺序,以正确的组合友元。

嵌套类是在其他类中声明的类,它有助于设计这样的助手类,即实现其他类,但不必是公有接口的组成部分。

C++异常机制为处理拙劣的编程时间,如不适当的值、I/O失败等,提供了一种灵活的方式。引发一场将终止当前执行的函数,将控制权传给匹配的catch块。catch块紧跟在try块的后面,为捕获异常,直接或间接导致异常的函数调用必须位于try块中。这样程序将执行catch块中的代码。这些代码试图解决问题或终止程序。类可以包含嵌套的异常类,嵌套异常类在相应的问题被发现时将被引发。函数可以包含异常规范,指出在该函数中可能引发的异常;但C++11摒弃了这项功能。未被捕获的异常(没有匹配的catch块的异常)在默认情况下将终止程序,意外异常(不与任何异常规范匹配的异常)也是如此。

RTTI(运行阶段类型信息)特性让程序能够检测对象的类型。dynamic_cast运算符用于将派生类指针转换为基类指针,其主要用途是确保可以安全地调用虚函数。typeid运算符返回一个tpye_info对象。可以对两个typeid的返回值进行比较,以确定对象是否为特定的类型,而返回的type_info对象可用于获得关于对象的信息。

与通用的转换机制相比,dynamic_cast, static_cast, const_cast和reinterpret_cast提供了更安全、更明确的类型转换。


http://www.ppmy.cn/ops/25970.html

相关文章

数据结构与算法学习笔记三---队列的表示和实现(C语言)

目录 前言 1.定义 2.队列的表示和实现 1.链队列 1.定义 2.初始化 3.入队 4.出队 5.队列为空 6.队列长度 7.清空队列 8.获取队首元素 9.完整代码 2.顺序队列 1.定义 2.初始化 3.入队 4.出队 5.队列为空 6.队列长度 7.清空队列 8.获取队首元素 9…

K8S集群安装

安装Docker sudo yum remove docker* sudo yum install -yum-utils ​ #配置docker的yum镜像仓库 sudo yum-config-manager \ --add-rep \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo ​ #安装指定版本docker... sudo yum install -y docker-ce-19.03…

视觉语言模型详解

视觉语言模型可以同时从图像和文本中学习,因此可用于视觉问答、图像描述等多种任务。本文,我们将带大家一览视觉语言模型领域: 作个概述、了解其工作原理、搞清楚如何找到真命天“模”、如何对其进行推理以及如何使用最新版的 trl 轻松对其进行微调。 什…

开发一个语音聊天社交app小程序H5需要多少钱?

社交,即时通讯APP系统。如何开发一个社交App||开发一个即时通信应用是一项复杂而充满挑战的任务,需要考虑多个技术、开发时间和功能方面的因素。以下是一个概要,描述了从技术、开发时间和功能角度如何开发这样的应用: 1. 技术要点…

[note]李宏毅Deep Learning 之 BackPropagation笔记

文章目录 Gradient DescentMath premiseBack Propagationforward passbackward pass Summary 中文名:反向传播算法 用于Gradient Descent 来train 一个neural network时用到 BackPropagation的核心是通过链式法则改变微分形式,并用forward pass 与 back…

【论文笔记】Training language models to follow instructions with human feedback A部分

Training language models to follow instructions with human feedback A 部分 回顾一下第一代 GPT-1 : 设计思路是 “海量无标记文本进行无监督预训练少量有标签文本有监督微调” 范式;模型架构是基于 Transformer 的叠加解码器(掩码自注意…

【后端】rabbitmq常见使用问题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、rabbitmq常见问题二、rabbitmq常见报错三、总结 前言 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多…

java+jsp+Oracle+Tomcat 记账管理系统论文(一)

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️ ➡️点击免费下载全套资料:源码、数据库、部署教程、论文、答辩ppt一条龙服务 ➡️有部署问题可私信联系 ⬆️⬆️⬆️​​​​​​​⬆️…