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

devtools/2024/10/18 18:27:31/

 友元

友元函数:

友元函数不是类的成员函数,但能够访问类的私有(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/devtools/26631.html

相关文章

UE5像素流部署以及多实例部署(兼容ue4)

像素流部署请看我之前的文章就行,今天讲的是多实例部署 在这里可以配置多实例的数量 如果设置800端口 设置两个实例 那么就是800 801端口 我的个人显卡是4060TI,最多开三个

vue3的v-model在组件上几种用法

文章目录 父组件1、update和 : 拆开使用2、computed 计算属性方法3、defineModel (3.4) 官方推荐4、TS泛型用法(3.3) 父组件 <template><div><button click"dialogVisible !dialogVisible">打开/关闭</button><ModalComp v-model"…

探索潜力:中心化交易所平台币的对比分析

核心观点 平台币在过去一年里表现差异显著&#xff1a; 在过去的一年里&#xff0c;只有少数几个平台币如BMX、BGB和MX的涨幅超过了100%。相比之下&#xff0c;由于市值较高&#xff0c;BNB和OKB的涨幅相对较低。 回购和销毁机制在平台币价值中起决定性作用&#xff1a; 像M…

solidity(15)

Solidity 中的控制流结构非常类似于其他编程语言,它允许开发者根据条件执行代码段。控制流对于任何能够运行更加复杂逻辑的智能合约系统至关重要。以下是 Solidity 主要的控制流结构: 🔄 if-else 控制结构: 💡 Copy code // 判断数字是否为0的示例函数 function ifEls…

展会资讯 | 现场精彩回顾 阿尔泰科技参展2024第23届中国国际(西部)光电产业!

2024第23届中国国际&#xff08;西部&#xff09;光电产业博览会&#xff0c;在成都世纪城新国际会展中心圆满落幕&#xff01;来自各地的光电领域设备及材料厂商汇聚一堂&#xff0c;展示前沿技术及创新成果。 展会现场&#xff0c;来自全国各地的500余家企业就精密光学、信息…

JS设置Ajax为同步或异步

在使用 AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;时&#xff0c;可以通过设置 XMLHttpRequest 对象的 async 属性来控制请求是同步&#xff08;synchronous&#xff09;还是异步&#xff08;asynchronous&#xff09;。 异步&#xff08;Asynchronous&…

npm install digital envelope routines::unsupported解决方法

目录 一、问题描述二、问题原因三、解决方法 一、问题描述 执行命令 npm install 报错&#xff1a;digital envelope routines::unsupported 二、问题原因 Node.js 17 版本引入了 OpenSSL 3.0&#xff0c;它在算法和密钥大小方面实施了更为严格的限制。这一变化导致 npm 的升…

店匠科技技术产品闪耀,引领新质生产力发展

在科技飞速发展的今天,新质生产力正成为推动社会进步和经济高质量发展的核心力量。店匠科技,作为一家致力于为全球B2C电商提供产品和技术解决方案的领先企业,其技术产品不仅体现了新质生产力的创新特质,更在推动电商行业转型升级中发挥了重要作用。 新质生产力,以创新为主导,摆…