《深入理解C++11:C++ 11新特性解析与应用》——2.9 扩展的friend语法

简介: 本节书摘来自华章计算机《深入理解C++11:C++ 11新特性解析与应用》一书中的第2章,第2.9节,作者 IBM XL编译器中国开发团队,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.9 扩展的friend语法

类别:部分人

friend关键字在C++中是一个比较特别的存在。因为我们常常会发现,一些面向对象程序语言,比如Java,就没有定义friend关键字。friend关键字用于声明类的友元,友元可以无视类中成员的属性。无论成员是public、protected或是private的,友元类或友元函数都可以访问,这就完全破坏了面向对象编程中封装性的概念。因此,使用friend关键字充满了争议性。在通常情况下,面向对象程序开发的专家会建议程序员使用Get/Set接口来访问类的成员,但有的时候,friend关键字确实会让程序员少写很多代码。因此即使存在争论,friend还是在很多程序中被使用到。而C++11对friend关键字进行了一些改进,以保证其更加好用。我们可以看看下面的例子,如代码清单2-19所示。

image
image

在代码清单2-19中,我们声明了3个类型:LiLei、Jim和HanMeiMei,它们都有一个友元类型Poly。从编译通过与否的状况中我们可以看出,在C++11中,声明一个类为另外一个类的友元时,不再需要使用class关键字。本例中的Jim和HanMeiMei就是这样一种情况,在HanMeiMei的声明中,我们甚至还使用了Poly的别名P,这同样是可行的。

虽然在C++11中这是一个小的改进,却会带来一点应用的变化—程序员可以为类模板声明友元了。这在C++98中是无法做到的。比如下面这个例子,如代码清单2-20所示。

image

从代码清单2-20中我们看到,对于People这个模板类,在使用类P为模板参数时,P是People

的一个friend类。而在使用内置类型int作为模板参数的时候,People会被实例化为一个普通的没有友元定义的类型。这样一来,我们就可以在模板实例化时才确定一个模板类是否有友元,以及谁是这个模板类的友元。这是一个非常有趣的小特性,在编写一些测试用例的时候,使用该特性是很有好处的。我们看看下面的例子,该例子源自一个实际的测试用例,如代码清单2-21所示。

image
image
image

在代码清单2-21所示的这个例子中,测试人员的目的是在一系列函数调用后,检查Attacker类变量a和Defender类变量d中成员变量的值是否符合预期。这里,按照封装的思想,所有成员变量被声明为private的。但Attacker和Defender的开发者为了方便,并没有为每个成员写Get函数,也没有为Attacker和Defender增加友元定义。而测试人员为了能够快速写出测试程序,采用了比较危险的做法,即使用宏将private关键字统一替换为public关键字。这样一来,类中的private成员就都成了public的。这样的做法存在4个缺点:一是如果侥幸程序中没有变量包含private字符串,该方法可以正常工作,但反之,则有可能导致严重的编译时错误;二是这种做法会降低代码可读性,因为改变了一个常见关键字的意义,没有注意到这个宏的程序员可能会非常迷惑程序的行为;三是如果在类的成员定义时不指定关键字(如public、private、protect等),而使用默认的private成员访问限制,那么该方法也不能达到目的;四则很简单,这样的做法看起来也并不漂亮。

不过由于有了扩展的friend声明,在C++11中,我们可以将Defender和Attacker类改良一下。我们看看下面的例子,如代码清单2-22所示。

image
image
image

在代码清单2-22中,我们把原有的Defender和Attacker类定义为模板类DefenderT和AttackerT。而在需要进行测试的时候,我们使用Validator为模板参数,实例化出DefenderTest及AttackerTest版本的类,这个版本的特点是,Validator是它们的友元,可以任意访问任何成员函数。而另外一个版本则是使用int类型进行实例化的Defender和Attacker,按照C++11的定义,它们不会有友元。因此这个版本保持了良好的封装性,可以用于提供接口用于常规使用。

值得注意的是,在代码清单2-22中,我们使用了using来定义类型的别名,这跟使用typedef的定义类型的别名是完全一样的。使用using定义类型别名是C++11中的一个新特性,我们可以在3.10节中看到相关的描述。

相关文章
|
4月前
|
Ubuntu API C++
C++标准库、Windows API及Ubuntu API的综合应用
总之,C++标准库、Windows API和Ubuntu API的综合应用是一项挑战性较大的任务,需要开发者具备跨平台编程的深入知识和丰富经验。通过合理的架构设计和有效的工具选择,可以在不同的操作系统平台上高效地开发和部署应用程序。
217 11
|
4月前
|
存储 编译器 开发工具
01.C++基础语法
本教程系统讲解C++基础语法,涵盖语言特性、编译器使用、命名空间、头文件、修饰符与关键字等核心内容,助你快速掌握C++编程基础。
345 9
|
10月前
|
机器学习/深度学习 文字识别 监控
安全监控系统:技术架构与应用解析
该系统采用模块化设计,集成了行为识别、视频监控、人脸识别、危险区域检测、异常事件检测、日志追溯及消息推送等功能,并可选配OCR识别模块。基于深度学习与开源技术栈(如TensorFlow、OpenCV),系统具备高精度、低延迟特点,支持实时分析儿童行为、监测危险区域、识别异常事件,并将结果推送给教师或家长。同时兼容主流硬件,支持本地化推理与分布式处理,确保可靠性与扩展性,为幼儿园安全管理提供全面解决方案。
499 3
|
11月前
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
327 15
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
11月前
|
人工智能 API 开发者
HarmonyOS Next~鸿蒙应用框架开发实战:Ability Kit与Accessibility Kit深度解析
本书深入解析HarmonyOS应用框架开发,聚焦Ability Kit与Accessibility Kit两大核心组件。Ability Kit通过FA/PA双引擎架构实现跨设备协同,支持分布式能力开发;Accessibility Kit提供无障碍服务构建方案,优化用户体验。内容涵盖设计理念、实践案例、调试优化及未来演进方向,助力开发者打造高效、包容的分布式应用,体现HarmonyOS生态价值。
707 27
|
11月前
|
供应链 项目管理 容器
深入探索 BPMN、CMMN 和 DMN:从定义到应用的全方位解析
在当今快速变化的商业环境中,对象管理组织(OMG)推出了三种强大的建模标准:BPMN(业务流程模型和符号)、CMMN(案例管理模型和符号)和DMN(决策模型和符号)。它们分别适用于结构化流程管理、动态案例处理和规则驱动的决策制定,并能相互协作,覆盖更广泛的业务场景。BPMN通过直观符号绘制固定流程;CMMN灵活管理不确定的案例;DMN以表格形式定义清晰的决策规则。三者结合可优化企业效率与灵活性。 [阅读更多](https://example.com/blog)
深入探索 BPMN、CMMN 和 DMN:从定义到应用的全方位解析
|
11月前
|
数据采集 机器学习/深度学习 存储
可穿戴设备如何重塑医疗健康:技术解析与应用实战
可穿戴设备如何重塑医疗健康:技术解析与应用实战
438 4
|
11月前
|
存储 弹性计算 安全
阿里云服务器ECS通用型规格族解析:实例规格、性能基准与场景化应用指南
作为ECS产品矩阵中的核心序列,通用型规格族以均衡的计算、内存、网络和存储性能著称,覆盖从基础应用到高性能计算的广泛场景。通用型规格族属于独享型云服务器,实例采用固定CPU调度模式,实例的每个CPU绑定到一个物理CPU超线程,实例间无CPU资源争抢,实例计算性能稳定且有严格的SLA保证,在性能上会更加稳定,高负载情况下也不会出现资源争夺现象。本文将深度解析阿里云ECS通用型规格族的技术架构、实例规格特性、最新价格政策及典型应用场景,为云计算选型提供参考。
|
11月前
|
设计模式 SQL Java
【再谈设计模式】解释器模式~语法的解析执行者
解释器模式定义了一种语言的语法表示,并定义一个解释器来解释该语言中的句子。它使用类来表示每个语法规则,并且通过递归调用这些类的方法来解释表达式。本质上,它将一个复杂的表达式分解为一系列简单的部分,然后按照特定的语法规则进行解析和执行。
318 8

推荐镜像

更多
  • DNS